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 "common/string.h"
#include "dumputils.h"
#include "fe_utils/string_utils.h"
#include "lib/stringinfo.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)
 
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 (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 (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 43 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 44 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 2260 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::public, _archiveHandle::SetupWorkerPtr, _archiveHandle::sqlparse, Archive::std_strings, generate_unaccent_rules::stdout, _archiveHandle::toc, and _archiveHandle::version.

Referenced by CreateArchive(), and OpenArchive().

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

◆ _becomeOwner()

static void _becomeOwner ( ArchiveHandle AH,
TocEntry te 
)
static

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

3271 {
3272  RestoreOptions *ropt = AH->public.ropt;
3273 
3274  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3275  return;
3276 
3277  _becomeUser(AH, te->owner);
3278 }
RestoreOptions * ropt
Definition: pg_backup.h:191
static void _becomeUser(ArchiveHandle *AH, const char *user)
int use_setsessauth
Definition: pg_backup.h:82

◆ _becomeUser()

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

Definition at line 3246 of file pg_backup_archiver.c.

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

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

3247 {
3248  if (!user)
3249  user = ""; /* avoid null pointers */
3250 
3251  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3252  return; /* no need to do anything */
3253 
3254  _doSetSessionAuth(AH, user);
3255 
3256  /*
3257  * NOTE: currUser keeps track of what the imaginary session user in our
3258  * script is
3259  */
3260  if (AH->currUser)
3261  free(AH->currUser);
3262  AH->currUser = pg_strdup(user);
3263 }
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:95

◆ _disableTriggersIfNecessary()

static void _disableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

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

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

◆ _discoverArchiveFormat()

static int _discoverArchiveFormat ( ArchiveHandle AH)
static

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

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

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

◆ _doSetSessionAuth()

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

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

3164 {
3166 
3167  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3168 
3169  /*
3170  * SQL requires a string literal here. Might as well be correct.
3171  */
3172  if (user && *user)
3173  appendStringLiteralAHX(cmd, user, AH);
3174  else
3175  appendPQExpBufferStr(cmd, "DEFAULT");
3176  appendPQExpBufferChar(cmd, ';');
3177 
3178  if (RestoringToDB(AH))
3179  {
3180  PGresult *res;
3181 
3182  res = PQexec(AH->connection, cmd->data);
3183 
3184  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3185  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3186  fatal("could not set session user to \"%s\": %s",
3188 
3189  PQclear(res);
3190  }
3191  else
3192  ahprintf(AH, "%s\n\n", cmd->data);
3193 
3194  destroyPQExpBuffer(cmd);
3195 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6666
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:95
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ _enableTriggersIfNecessary()

static void _enableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

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

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

◆ _getObjectDescription()

static void _getObjectDescription ( PQExpBuffer  buf,
TocEntry te 
)
static

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

3445 {
3446  const char *type = te->desc;
3447 
3448  /* Use ALTER TABLE for views and sequences */
3449  if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0 ||
3450  strcmp(type, "MATERIALIZED VIEW") == 0)
3451  type = "TABLE";
3452 
3453  /* objects that don't require special decoration */
3454  if (strcmp(type, "COLLATION") == 0 ||
3455  strcmp(type, "CONVERSION") == 0 ||
3456  strcmp(type, "DOMAIN") == 0 ||
3457  strcmp(type, "TABLE") == 0 ||
3458  strcmp(type, "TYPE") == 0 ||
3459  strcmp(type, "FOREIGN TABLE") == 0 ||
3460  strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
3461  strcmp(type, "TEXT SEARCH CONFIGURATION") == 0 ||
3462  strcmp(type, "STATISTICS") == 0 ||
3463  /* non-schema-specified objects */
3464  strcmp(type, "DATABASE") == 0 ||
3465  strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
3466  strcmp(type, "SCHEMA") == 0 ||
3467  strcmp(type, "EVENT TRIGGER") == 0 ||
3468  strcmp(type, "FOREIGN DATA WRAPPER") == 0 ||
3469  strcmp(type, "SERVER") == 0 ||
3470  strcmp(type, "PUBLICATION") == 0 ||
3471  strcmp(type, "SUBSCRIPTION") == 0 ||
3472  strcmp(type, "USER MAPPING") == 0)
3473  {
3474  appendPQExpBuffer(buf, "%s ", type);
3475  if (te->namespace && *te->namespace)
3476  appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));
3477  appendPQExpBufferStr(buf, fmtId(te->tag));
3478  return;
3479  }
3480 
3481  /* BLOBs just have a name, but it's numeric so must not use fmtId */
3482  if (strcmp(type, "BLOB") == 0)
3483  {
3484  appendPQExpBuffer(buf, "LARGE OBJECT %s", te->tag);
3485  return;
3486  }
3487 
3488  /*
3489  * These object types require additional decoration. Fortunately, the
3490  * information needed is exactly what's in the DROP command.
3491  */
3492  if (strcmp(type, "AGGREGATE") == 0 ||
3493  strcmp(type, "FUNCTION") == 0 ||
3494  strcmp(type, "OPERATOR") == 0 ||
3495  strcmp(type, "OPERATOR CLASS") == 0 ||
3496  strcmp(type, "OPERATOR FAMILY") == 0 ||
3497  strcmp(type, "PROCEDURE") == 0)
3498  {
3499  /* Chop "DROP " off the front and make a modifiable copy */
3500  char *first = pg_strdup(te->dropStmt + 5);
3501  char *last;
3502 
3503  /* point to last character in string */
3504  last = first + strlen(first) - 1;
3505 
3506  /* Strip off any ';' or '\n' at the end */
3507  while (last >= first && (*last == '\n' || *last == ';'))
3508  last--;
3509  *(last + 1) = '\0';
3510 
3511  appendPQExpBufferStr(buf, first);
3512 
3513  free(first);
3514  return;
3515  }
3516 
3517  pg_log_warning("don't know how to set owner for object type \"%s\"",
3518  type);
3519 }
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 ( TocEntry pos,
TocEntry te 
)
static

Definition at line 1792 of file pg_backup_archiver.c.

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

Referenced by SortTocFromFile().

1793 {
1794  /* Unlink te from list */
1795  te->prev->next = te->next;
1796  te->next->prev = te->prev;
1797 
1798  /* and insert it before "pos" */
1799  te->prev = pos->prev;
1800  te->next = pos;
1801  pos->prev->next = te;
1802  pos->prev = te;
1803 }
struct _tocEntry * next
struct _tocEntry * prev

◆ _printTocEntry()

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

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

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

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

◆ _selectOutputSchema()

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

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

3287 {
3288  PQExpBuffer qry;
3289 
3290  /*
3291  * If there was a SEARCHPATH TOC entry, we're supposed to just stay with
3292  * that search_path rather than switching to entry-specific paths.
3293  * Otherwise, it's an old archive that will not restore correctly unless
3294  * we set the search_path as it's expecting.
3295  */
3296  if (AH->public.searchpath)
3297  return;
3298 
3299  if (!schemaName || *schemaName == '\0' ||
3300  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3301  return; /* no need to do anything */
3302 
3303  qry = createPQExpBuffer();
3304 
3305  appendPQExpBuffer(qry, "SET search_path = %s",
3306  fmtId(schemaName));
3307  if (strcmp(schemaName, "pg_catalog") != 0)
3308  appendPQExpBufferStr(qry, ", pg_catalog");
3309 
3310  if (RestoringToDB(AH))
3311  {
3312  PGresult *res;
3313 
3314  res = PQexec(AH->connection, qry->data);
3315 
3316  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3318  "could not set search_path to \"%s\": %s",
3319  schemaName, PQerrorMessage(AH->connection));
3320 
3321  PQclear(res);
3322  }
3323  else
3324  ahprintf(AH, "%s;\n\n", qry->data);
3325 
3326  if (AH->currSchema)
3327  free(AH->currSchema);
3328  AH->currSchema = pg_strdup(schemaName);
3329 
3330  destroyPQExpBuffer(qry);
3331 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6666
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:209
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 3399 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().

3400 {
3401  PQExpBuffer cmd;
3402  const char *want,
3403  *have;
3404 
3405  have = AH->currTableAm;
3406  want = tableam;
3407 
3408  if (!want)
3409  return;
3410 
3411  if (have && strcmp(want, have) == 0)
3412  return;
3413 
3414  cmd = createPQExpBuffer();
3415  appendPQExpBuffer(cmd, "SET default_table_access_method = %s;", fmtId(want));
3416 
3417  if (RestoringToDB(AH))
3418  {
3419  PGresult *res;
3420 
3421  res = PQexec(AH->connection, cmd->data);
3422 
3423  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3425  "could not set default_table_access_method: %s",
3426  PQerrorMessage(AH->connection));
3427 
3428  PQclear(res);
3429  }
3430  else
3431  ahprintf(AH, "%s\n\n", cmd->data);
3432 
3433  destroyPQExpBuffer(cmd);
3434 
3435  AH->currTableAm = pg_strdup(want);
3436 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6666
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 3338 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().

3339 {
3340  RestoreOptions *ropt = AH->public.ropt;
3341  PQExpBuffer qry;
3342  const char *want,
3343  *have;
3344 
3345  /* do nothing in --no-tablespaces mode */
3346  if (ropt->noTablespace)
3347  return;
3348 
3349  have = AH->currTablespace;
3350  want = tablespace;
3351 
3352  /* no need to do anything for non-tablespace object */
3353  if (!want)
3354  return;
3355 
3356  if (have && strcmp(want, have) == 0)
3357  return; /* no need to do anything */
3358 
3359  qry = createPQExpBuffer();
3360 
3361  if (strcmp(want, "") == 0)
3362  {
3363  /* We want the tablespace to be the database's default */
3364  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3365  }
3366  else
3367  {
3368  /* We want an explicit tablespace */
3369  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3370  }
3371 
3372  if (RestoringToDB(AH))
3373  {
3374  PGresult *res;
3375 
3376  res = PQexec(AH->connection, qry->data);
3377 
3378  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3380  "could not set default_tablespace to %s: %s",
3381  fmtId(want), PQerrorMessage(AH->connection));
3382 
3383  PQclear(res);
3384  }
3385  else
3386  ahprintf(AH, "%s;\n\n", qry->data);
3387 
3388  if (AH->currTablespace)
3389  free(AH->currTablespace);
3390  AH->currTablespace = pg_strdup(want);
3391 
3392  destroyPQExpBuffer(qry);
3393 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6666
RestoreOptions * ropt
Definition: pg_backup.h:191
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:189
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 3095 of file pg_backup_archiver.c.

References _tocEntry::desc.

Referenced by _printTocEntry(), and _tocEntryRequired().

3096 {
3097  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3098  if (strcmp(te->desc, "ACL") == 0 ||
3099  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3100  strcmp(te->desc, "DEFAULT ACL") == 0)
3101  return true;
3102  return false;
3103 }

◆ _tocEntryRequired()

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

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

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

◆ _tocEntryRestorePass()

static RestorePass _tocEntryRestorePass ( TocEntry te)
static

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

3063 {
3064  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3065  if (strcmp(te->desc, "ACL") == 0 ||
3066  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3067  strcmp(te->desc, "DEFAULT ACL") == 0)
3068  return RESTORE_PASS_ACL;
3069  if (strcmp(te->desc, "EVENT TRIGGER") == 0 ||
3070  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0)
3071  return RESTORE_PASS_POST_ACL;
3072 
3073  /*
3074  * Comments need to be emitted in the same pass as their parent objects.
3075  * ACLs haven't got comments, and neither do matview data objects, but
3076  * event triggers do. (Fortunately, event triggers haven't got ACLs, or
3077  * we'd need yet another weird special case.)
3078  */
3079  if (strcmp(te->desc, "COMMENT") == 0 &&
3080  strncmp(te->tag, "EVENT TRIGGER ", 14) == 0)
3081  return RESTORE_PASS_POST_ACL;
3082 
3083  /* All else can be handled in the main pass. */
3084  return RESTORE_PASS_MAIN;
3085 }

◆ ahprintf()

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

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

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

1679 {
1680  int bytes_written = 0;
1681 
1682  if (AH->writingBlob)
1683  {
1684  size_t remaining = size * nmemb;
1685 
1686  while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1687  {
1688  size_t avail = AH->lo_buf_size - AH->lo_buf_used;
1689 
1690  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1691  ptr = (const void *) ((const char *) ptr + avail);
1692  remaining -= avail;
1693  AH->lo_buf_used += avail;
1694  dump_lo_buf(AH);
1695  }
1696 
1697  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1698  AH->lo_buf_used += remaining;
1699 
1700  bytes_written = size * nmemb;
1701  }
1702  else if (AH->gzOut)
1703  bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
1704  else if (AH->CustomOutPtr)
1705  bytes_written = AH->CustomOutPtr(AH, ptr, size * nmemb);
1706 
1707  else
1708  {
1709  /*
1710  * If we're doing a restore, and it's direct to DB, and we're
1711  * connected then send it to the DB.
1712  */
1713  if (RestoringToDB(AH))
1714  bytes_written = ExecuteSqlCommandBuf(&AH->public, (const char *) ptr, size * nmemb);
1715  else
1716  bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
1717  }
1718 
1719  if (bytes_written != size * nmemb)
1721 }
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:451
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 1057 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().

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

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

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

References WriteData().

Referenced by dumpTableData_insert().

1445 {
1446  WriteData(AH, s, strlen(s));
1447 }
void WriteData(Archive *AHX, const void *data, size_t dLen)

◆ buildTocEntryArrays()

static void buildTocEntryArrays ( ArchiveHandle AH)
static

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

1818 {
1819  DumpId maxDumpId = AH->maxDumpId;
1820  TocEntry *te;
1821 
1822  AH->tocsByDumpId = (TocEntry **) pg_malloc0((maxDumpId + 1) * sizeof(TocEntry *));
1823  AH->tableDataId = (DumpId *) pg_malloc0((maxDumpId + 1) * sizeof(DumpId));
1824 
1825  for (te = AH->toc->next; te != AH->toc; te = te->next)
1826  {
1827  /* this check is purely paranoia, maxDumpId should be correct */
1828  if (te->dumpId <= 0 || te->dumpId > maxDumpId)
1829  fatal("bad dumpId");
1830 
1831  /* tocsByDumpId indexes all TOCs by their dump ID */
1832  AH->tocsByDumpId[te->dumpId] = te;
1833 
1834  /*
1835  * tableDataId provides the TABLE DATA item's dump ID for each TABLE
1836  * TOC entry that has a DATA item. We compute this by reversing the
1837  * TABLE DATA item's dependency, knowing that a TABLE DATA item has
1838  * just one dependency and it is the TABLE item.
1839  */
1840  if (strcmp(te->desc, "TABLE DATA") == 0 && te->nDeps > 0)
1841  {
1842  DumpId tableId = te->dependencies[0];
1843 
1844  /*
1845  * The TABLE item might not have been in the archive, if this was
1846  * a data-only dump; but its dump ID should be less than its data
1847  * item's dump ID, so there should be a place for it in the array.
1848  */
1849  if (tableId <= 0 || tableId > maxDumpId)
1850  fatal("bad table dumpId for TABLE DATA item");
1851 
1852  AH->tableDataId[tableId] = te->dumpId;
1853  }
1854  }
1855 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:242
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 3861 of file pg_backup_archiver.c.

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3862 {
3863  pgoff_t tpos;
3864 
3865  /* Check that ftello works on this file */
3866  tpos = ftello(fp);
3867  if (tpos < 0)
3868  return false;
3869 
3870  /*
3871  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3872  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3873  * successful no-op even on files that are otherwise unseekable.
3874  */
3875  if (fseeko(fp, tpos, SEEK_SET) != 0)
3876  return false;
3877 
3878  return true;
3879 }
#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 4785 of file pg_backup_archiver.c.

References _doSetFixedOutputState(), archModeRead, Assert, _archiveHandle::connCancel, ConnectDatabase(), _archiveHandle::connection, _restoreOptions::cparams, _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::mode, Archive::n_errors, pg_malloc(), pg_strdup(), _archiveHandle::public, Archive::ropt, _archiveHandle::savedPassword, and _archiveHandle::sqlparse.

Referenced by RunWorker().

4786 {
4787  ArchiveHandle *clone;
4788 
4789  /* Make a "flat" copy */
4790  clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
4791  memcpy(clone, AH, sizeof(ArchiveHandle));
4792 
4793  /* Handle format-independent fields */
4794  memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse));
4795 
4796  /* The clone will have its own connection, so disregard connection state */
4797  clone->connection = NULL;
4798  clone->connCancel = NULL;
4799  clone->currUser = NULL;
4800  clone->currSchema = NULL;
4801  clone->currTablespace = NULL;
4802 
4803  /* savedPassword must be local in case we change it while connecting */
4804  if (clone->savedPassword)
4805  clone->savedPassword = pg_strdup(clone->savedPassword);
4806 
4807  /* clone has its own error count, too */
4808  clone->public.n_errors = 0;
4809 
4810  /*
4811  * Connect our new clone object to the database, using the same connection
4812  * parameters used for the original connection.
4813  */
4814  ConnectDatabase((Archive *) clone, &clone->public.ropt->cparams, true);
4815 
4816  /* re-establish fixed state */
4817  if (AH->mode == archModeRead)
4818  _doSetFixedOutputState(clone);
4819  /* in write case, setupDumpWorker will fix up connection state */
4820 
4821  /* Let the format-specific code have a chance too */
4822  clone->ClonePtr(clone);
4823 
4824  Assert(clone->connection != NULL);
4825  return clone;
4826 }
void ConnectDatabase(Archive *AHX, const ConnParams *cparams, bool isReconnect)
Definition: pg_backup_db.c:114
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
RestoreOptions * ropt
Definition: pg_backup.h:191
int n_errors
Definition: pg_backup.h:214
PGcancel *volatile connCancel
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void _doSetFixedOutputState(ArchiveHandle *AH)
sqlparseInfo sqlparse
ConnParams cparams
Definition: pg_backup.h:124
#define Assert(condition)
Definition: c.h:745
ClonePtrType ClonePtr

◆ CloseArchive()

void CloseArchive ( Archive AHX)

Definition at line 263 of file pg_backup_archiver.c.

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

Referenced by main().

264 {
265  int res = 0;
266  ArchiveHandle *AH = (ArchiveHandle *) AHX;
267 
268  AH->ClosePtr(AH);
269 
270  /* Close the output */
271  if (AH->gzOut)
272  res = GZCLOSE(AH->OF);
273  else if (AH->OF != stdout)
274  res = fclose(AH->OF);
275 
276  if (res != 0)
277  fatal("could not close output file: %m");
278 }
#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 240 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

244 {
245  ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, dosync,
247 
248  return (Archive *) AH;
249 }
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:1242

◆ DeCloneArchive()

void DeCloneArchive ( ArchiveHandle AH)

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

4835 {
4836  /* Should not have an open database connection */
4837  Assert(AH->connection == NULL);
4838 
4839  /* Clear format-specific state */
4840  AH->DeClonePtr(AH);
4841 
4842  /* Clear state allocated by CloneArchive */
4843  if (AH->sqlparse.curCmd)
4845 
4846  /* Clear any connection-local state */
4847  if (AH->currUser)
4848  free(AH->currUser);
4849  if (AH->currSchema)
4850  free(AH->currSchema);
4851  if (AH->currTablespace)
4852  free(AH->currTablespace);
4853  if (AH->currTableAm)
4854  free(AH->currTableAm);
4855  if (AH->savedPassword)
4856  free(AH->savedPassword);
4857 
4858  free(AH);
4859 }
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 1636 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().

1637 {
1638  if (AH->connection)
1639  {
1640  size_t res;
1641 
1642  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1643  pg_log_debug(ngettext("wrote %lu byte of large object data (result = %lu)",
1644  "wrote %lu bytes of large object data (result = %lu)",
1645  AH->lo_buf_used),
1646  (unsigned long) AH->lo_buf_used, (unsigned long) res);
1647  if (res != AH->lo_buf_used)
1648  fatal("could not write to large object (result: %lu, expected: %lu)",
1649  (unsigned long) res, (unsigned long) AH->lo_buf_used);
1650  }
1651  else
1652  {
1654 
1656  (const unsigned char *) AH->lo_buf,
1657  AH->lo_buf_used,
1658  AH);
1659 
1660  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1661  AH->writingBlob = 0;
1662  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1663  AH->writingBlob = 1;
1664 
1665  destroyPQExpBuffer(buf);
1666  }
1667  AH->lo_buf_used = 0;
1668 }
#define appendByteaLiteralAHX(buf, str, len, AH)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
#define pg_log_debug(...)
Definition: logging.h:92
static char * buf
Definition: pg_test_fsync.c:68
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:1123
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
#define fatal(...)

◆ dumpOptionsFromRestoreOptions()

DumpOptions* dumpOptionsFromRestoreOptions ( RestoreOptions ropt)

Definition at line 177 of file pg_backup_archiver.c.

References _restoreOptions::aclsSkip, _dumpOptions::aclsSkip, _restoreOptions::column_inserts, _dumpOptions::column_inserts, _restoreOptions::cparams, _dumpOptions::cparams, _restoreOptions::createDB, _restoreOptions::dataOnly, _dumpOptions::dataOnly, _connParams::dbname, _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, pg_strdup(), _connParams::pghost, _connParams::pgport, _connParams::promptPassword, _restoreOptions::schemaOnly, _dumpOptions::schemaOnly, _restoreOptions::sequence_data, _dumpOptions::sequence_data, _restoreOptions::superuser, _restoreOptions::use_setsessauth, _dumpOptions::use_setsessauth, and _connParams::username.

Referenced by SetArchiveOptions().

178 {
179  DumpOptions *dopt = NewDumpOptions();
180 
181  /* this is the inverse of what's at the end of pg_dump.c's main() */
182  dopt->cparams.dbname = ropt->cparams.dbname ? pg_strdup(ropt->cparams.dbname) : NULL;
183  dopt->cparams.pgport = ropt->cparams.pgport ? pg_strdup(ropt->cparams.pgport) : NULL;
184  dopt->cparams.pghost = ropt->cparams.pghost ? pg_strdup(ropt->cparams.pghost) : NULL;
185  dopt->cparams.username = ropt->cparams.username ? pg_strdup(ropt->cparams.username) : NULL;
187  dopt->outputClean = ropt->dropSchema;
188  dopt->dataOnly = ropt->dataOnly;
189  dopt->schemaOnly = ropt->schemaOnly;
190  dopt->if_exists = ropt->if_exists;
191  dopt->column_inserts = ropt->column_inserts;
192  dopt->dumpSections = ropt->dumpSections;
193  dopt->aclsSkip = ropt->aclsSkip;
194  dopt->outputSuperuser = ropt->superuser;
195  dopt->outputCreateDB = ropt->createDB;
196  dopt->outputNoOwner = ropt->noOwner;
197  dopt->outputNoTablespaces = ropt->noTablespace;
198  dopt->disable_triggers = ropt->disable_triggers;
199  dopt->use_setsessauth = ropt->use_setsessauth;
201  dopt->dump_inserts = ropt->dump_inserts;
202  dopt->no_comments = ropt->no_comments;
203  dopt->no_publications = ropt->no_publications;
205  dopt->no_subscriptions = ropt->no_subscriptions;
206  dopt->lockWaitTimeout = ropt->lockWaitTimeout;
209  dopt->sequence_data = ropt->sequence_data;
210 
211  return dopt;
212 }
int column_inserts
Definition: pg_backup.h:155
int disable_triggers
Definition: pg_backup.h:164
int disable_dollar_quoting
Definition: pg_backup.h:87
char * pgport
Definition: pg_backup.h:66
bool schemaOnly
Definition: pg_backup.h:146
int no_subscriptions
Definition: pg_backup.h:160
int no_publications
Definition: pg_backup.h:159
DumpOptions * NewDumpOptions(void)
int sequence_data
Definition: pg_backup.h:180
trivalue promptPassword
Definition: pg_backup.h:69
char * dbname
Definition: pg_backup.h:65
const char * lockWaitTimeout
Definition: pg_backup.h:103
int use_setsessauth
Definition: pg_backup.h:166
int disable_dollar_quoting
Definition: pg_backup.h:154
int column_inserts
Definition: pg_backup.h:89
const char * lockWaitTimeout
Definition: pg_backup.h:150
bool dataOnly
Definition: pg_backup.h:147
bool include_everything
Definition: pg_backup.h:171
char * outputSuperuser
Definition: pg_backup.h:178
ConnParams cparams
Definition: pg_backup.h:141
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int include_everything
Definition: pg_backup.h:104
int no_security_labels
Definition: pg_backup.h:93
int dumpSections
Definition: pg_backup.h:148
int enable_row_security
Definition: pg_backup.h:134
int dump_inserts
Definition: pg_backup.h:151
int outputNoOwner
Definition: pg_backup.h:177
ConnParams cparams
Definition: pg_backup.h:124
int no_security_labels
Definition: pg_backup.h:158
char * pghost
Definition: pg_backup.h:67
char * username
Definition: pg_backup.h:68
int no_subscriptions
Definition: pg_backup.h:94
char * superuser
Definition: pg_backup.h:84
bool aclsSkip
Definition: pg_backup.h:149
int use_setsessauth
Definition: pg_backup.h:82
int enable_row_security
Definition: pg_backup.h:167
int outputCreateDB
Definition: pg_backup.h:174
int outputClean
Definition: pg_backup.h:173
int no_comments
Definition: pg_backup.h:157
int outputNoTablespaces
Definition: pg_backup.h:165
int no_publications
Definition: pg_backup.h:92
int disable_triggers
Definition: pg_backup.h:80

◆ dumpTimestamp()

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

Definition at line 3886 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3887 {
3888  char buf[64];
3889 
3890  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3891  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3892 }
static char * buf
Definition: pg_test_fsync.c:68
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 1233 of file pg_backup_archiver.c.

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

Referenced by dumpBlobs().

1234 {
1235  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1236 
1237  if (AH->EndBlobPtr)
1238  AH->EndBlobPtr(AH, AH->currToc, oid);
1239 
1240  return 1;
1241 }
struct _tocEntry * currToc
EndBlobPtrType EndBlobPtr

◆ EndRestoreBlob()

void EndRestoreBlob ( ArchiveHandle AH,
Oid  oid 
)

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

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

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

◆ fix_dependencies()

static void fix_dependencies ( ArchiveHandle AH)
static

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

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

References buildTocEntryArrays(), and _archiveHandle::tocsByDumpId.

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

1859 {
1860  /* build index arrays if we didn't already */
1861  if (AH->tocsByDumpId == NULL)
1862  buildTocEntryArrays(AH);
1863 
1864  if (id > 0 && id <= AH->maxDumpId)
1865  return AH->tocsByDumpId[id];
1866 
1867  return NULL;
1868 }
static void buildTocEntryArrays(ArchiveHandle *AH)
struct _tocEntry ** tocsByDumpId

◆ has_lock_conflicts()

static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 4173 of file pg_backup_archiver.c.

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

Referenced by pop_next_work_item().

4174 {
4175  int j,
4176  k;
4177 
4178  for (j = 0; j < te1->nLockDeps; j++)
4179  {
4180  for (k = 0; k < te2->nDeps; k++)
4181  {
4182  if (te1->lockDeps[j] == te2->dependencies[k])
4183  return true;
4184  }
4185  }
4186  return false;
4187 }
DumpId * lockDeps
DumpId * dependencies

◆ identify_locking_dependencies()

static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

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

4647 {
4648  DumpId *lockids;
4649  int nlockids;
4650  int i;
4651 
4652  /*
4653  * We only care about this for POST_DATA items. PRE_DATA items are not
4654  * run in parallel, and DATA items are all independent by assumption.
4655  */
4656  if (te->section != SECTION_POST_DATA)
4657  return;
4658 
4659  /* Quick exit if no dependencies at all */
4660  if (te->nDeps == 0)
4661  return;
4662 
4663  /*
4664  * Most POST_DATA items are ALTER TABLEs or some moral equivalent of that,
4665  * and hence require exclusive lock. However, we know that CREATE INDEX
4666  * does not. (Maybe someday index-creating CONSTRAINTs will fall in that
4667  * category too ... but today is not that day.)
4668  */
4669  if (strcmp(te->desc, "INDEX") == 0)
4670  return;
4671 
4672  /*
4673  * We assume the entry requires exclusive lock on each TABLE or TABLE DATA
4674  * item listed among its dependencies. Originally all of these would have
4675  * been TABLE items, but repoint_table_dependencies would have repointed
4676  * them to the TABLE DATA items if those are present (which they might not
4677  * be, eg in a schema-only dump). Note that all of the entries we are
4678  * processing here are POST_DATA; otherwise there might be a significant
4679  * difference between a dependency on a table and a dependency on its
4680  * data, so that closer analysis would be needed here.
4681  */
4682  lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
4683  nlockids = 0;
4684  for (i = 0; i < te->nDeps; i++)
4685  {
4686  DumpId depid = te->dependencies[i];
4687 
4688  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL &&
4689  ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) ||
4690  strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0))
4691  lockids[nlockids++] = depid;
4692  }
4693 
4694  if (nlockids == 0)
4695  {
4696  free(lockids);
4697  return;
4698  }
4699 
4700  te->lockDeps = pg_realloc(lockids, nlockids * sizeof(DumpId));
4701  te->nLockDeps = nlockids;
4702 }
int DumpId
Definition: pg_backup.h:242
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 4765 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().

4766 {
4767  pg_log_info("table \"%s\" could not be created, will not restore its data",
4768  te->tag);
4769 
4770  if (AH->tableDataId[te->dumpId] != 0)
4771  {
4772  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4773 
4774  ted->reqs = 0;
4775  }
4776 }
struct _tocEntry ** tocsByDumpId
#define pg_log_info(...)
Definition: logging.h:88

◆ InitDumpOptions()

void InitDumpOptions ( DumpOptions opts)

Definition at line 163 of file pg_backup_archiver.c.

References _dumpOptions::cparams, DUMP_UNSECTIONED, _dumpOptions::dumpSections, _dumpOptions::include_everything, _connParams::promptPassword, and TRI_DEFAULT.

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;
170 }
trivalue promptPassword
Definition: pg_backup.h:69
bool include_everything
Definition: pg_backup.h:171
ConnParams cparams
Definition: pg_backup.h:141
int dumpSections
Definition: pg_backup.h:148

◆ mark_create_done()

static void mark_create_done ( ArchiveHandle AH,
TocEntry te 
)
static

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

4751 {
4752  if (AH->tableDataId[te->dumpId] != 0)
4753  {
4754  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4755 
4756  ted->created = true;
4757  }
4758 }
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 2440 of file pg_backup_archiver.c.

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

Referenced by WriteDataChunks().

2444 {
2445  pg_log_info("finished item %d %s %s",
2446  te->dumpId, te->desc, te->tag);
2447 
2448  if (status != 0)
2449  fatal("worker process failed: exit code %d",
2450  status);
2451 }
#define fatal(...)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227
#define pg_log_info(...)
Definition: logging.h:88

◆ mark_restore_job_done()

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

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

4445 {
4446  ParallelReadyList *ready_list = (ParallelReadyList *) callback_data;
4447 
4448  pg_log_info("finished item %d %s %s",
4449  te->dumpId, te->desc, te->tag);
4450 
4451  if (status == WORKER_CREATE_DONE)
4452  mark_create_done(AH, te);
4453  else if (status == WORKER_INHIBIT_DATA)
4454  {
4456  AH->public.n_errors++;
4457  }
4458  else if (status == WORKER_IGNORED_ERRORS)
4459  AH->public.n_errors++;
4460  else if (status != 0)
4461  fatal("worker process failed: exit code %d",
4462  status);
4463 
4464  reduce_dependencies(AH, te, ready_list);
4465 }
#define WORKER_CREATE_DONE
int n_errors
Definition: pg_backup.h:214
#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:227
#define pg_log_info(...)
Definition: logging.h:88

◆ move_to_ready_list()

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

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

4329 {
4330  TocEntry *te;
4331  TocEntry *next_te;
4332 
4333  for (te = pending_list->pending_next; te != pending_list; te = next_te)
4334  {
4335  /* must save list link before possibly removing te from list */
4336  next_te = te->pending_next;
4337 
4338  if (te->depCount == 0 &&
4339  _tocEntryRestorePass(te) == pass)
4340  {
4341  /* Remove it from pending_list ... */
4342  pending_list_remove(te);
4343  /* ... and add to ready_list */
4344  ready_list_insert(ready_list, te);
4345  }
4346  }
4347 }
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 964 of file pg_backup_archiver.c.

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

Referenced by _CloseArchive(), and main().

965 {
966  RestoreOptions *opts;
967 
968  opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions));
969 
970  /* set any fields that shouldn't default to zeroes */
971  opts->format = archUnknown;
974 
975  return opts;
976 }
trivalue promptPassword
Definition: pg_backup.h:69
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
ConnParams cparams
Definition: pg_backup.h:124

◆ OpenArchive()

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

Definition at line 254 of file pg_backup_archiver.c.

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

Referenced by main().

255 {
256  ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, true, archModeRead, setupRestoreWorker);
257 
258  return (Archive *) AH;
259 }
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 4418 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().

4419 {
4420  int status;
4421 
4422  Assert(AH->connection != NULL);
4423 
4424  /* Count only errors associated with this TOC entry */
4425  AH->public.n_errors = 0;
4426 
4427  /* Restore the TOC item */
4428  status = restore_toc_entry(AH, te, true);
4429 
4430  return status;
4431 }
int n_errors
Definition: pg_backup.h:214
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:227

◆ pending_list_append()

static void pending_list_append ( TocEntry l,
TocEntry te 
)
static

Definition at line 4205 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_prefork().

4206 {
4207  te->pending_prev = l->pending_prev;
4208  l->pending_prev->pending_next = te;
4209  l->pending_prev = te;
4210  te->pending_next = l;
4211 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_header_init()

static void pending_list_header_init ( TocEntry l)
static

Definition at line 4198 of file pg_backup_archiver.c.

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

Referenced by RestoreArchive().

4199 {
4200  l->pending_prev = l->pending_next = l;
4201 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_remove()

static void pending_list_remove ( TocEntry te)
static

Definition at line 4215 of file pg_backup_archiver.c.

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

Referenced by move_to_ready_list(), and reduce_dependencies().

4216 {
4219  te->pending_prev = NULL;
4220  te->pending_next = NULL;
4221 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pop_next_work_item()

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

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

4363 {
4364  /*
4365  * Sort the ready_list so that we'll tackle larger jobs first.
4366  */
4367  ready_list_sort(ready_list);
4368 
4369  /*
4370  * Search the ready_list until we find a suitable item.
4371  */
4372  for (int i = ready_list->first_te; i <= ready_list->last_te; i++)
4373  {
4374  TocEntry *te = ready_list->tes[i];
4375  bool conflicts = false;
4376 
4377  /*
4378  * Check to see if the item would need exclusive lock on something
4379  * that a currently running item also needs lock on, or vice versa. If
4380  * so, we don't want to schedule them together.
4381  */
4382  for (int k = 0; k < pstate->numWorkers; k++)
4383  {
4384  TocEntry *running_te = pstate->te[k];
4385 
4386  if (running_te == NULL)
4387  continue;
4388  if (has_lock_conflicts(te, running_te) ||
4389  has_lock_conflicts(running_te, te))
4390  {
4391  conflicts = true;
4392  break;
4393  }
4394  }
4395 
4396  if (conflicts)
4397  continue;
4398 
4399  /* passed all tests, so this item can run */
4400  ready_list_remove(ready_list, i);
4401  return te;
4402  }
4403 
4404  pg_log_debug("no item ready");
4405  return NULL;
4406 }
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:92
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 1115 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().

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

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

2703 {
2704  /* te->defn should have the form SET client_encoding = 'foo'; */
2705  char *defn = pg_strdup(te->defn);
2706  char *ptr1;
2707  char *ptr2 = NULL;
2708  int encoding;
2709 
2710  ptr1 = strchr(defn, '\'');
2711  if (ptr1)
2712  ptr2 = strchr(++ptr1, '\'');
2713  if (ptr2)
2714  {
2715  *ptr2 = '\0';
2716  encoding = pg_char_to_encoding(ptr1);
2717  if (encoding < 0)
2718  fatal("unrecognized encoding \"%s\"",
2719  ptr1);
2720  AH->public.encoding = encoding;
2721  }
2722  else
2723  fatal("invalid ENCODING item: %s",
2724  te->defn);
2725 
2726  free(defn);
2727 }
int pg_char_to_encoding(const char *name)
Definition: encnames.c:550
int encoding
Definition: pg_backup.h:205
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 2746 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2747 {
2748  /*
2749  * te->defn should contain a command to set search_path. We just copy it
2750  * verbatim for use later.
2751  */
2752  AH->public.searchpath = pg_strdup(te->defn);
2753 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char * searchpath
Definition: pg_backup.h:209

◆ processStdStringsEntry()

static void processStdStringsEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2730 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2731 {
2732  /* te->defn should have the form SET standard_conforming_strings = 'x'; */
2733  char *ptr1;
2734 
2735  ptr1 = strchr(te->defn, '\'');
2736  if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
2737  AH->public.std_strings = true;
2738  else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
2739  AH->public.std_strings = false;
2740  else
2741  fatal("invalid STDSTRINGS item: %s",
2742  te->defn);
2743 }
#define fatal(...)
bool std_strings
Definition: pg_backup.h:206

◆ ReadHead()

void ReadHead ( ArchiveHandle AH)

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

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

1995 {
1996  int res = 0;
1997  int bv,
1998  b;
1999  int sign = 0; /* Default positive */
2000  int bitShift = 0;
2001 
2002  if (AH->version > K_VERS_1_0)
2003  /* Read a sign byte */
2004  sign = AH->ReadBytePtr(AH);
2005 
2006  for (b = 0; b < AH->intSize; b++)
2007  {
2008  bv = AH->ReadBytePtr(AH) & 0xFF;
2009  if (bv != 0)
2010  res = res + (bv << bitShift);
2011  bitShift += 8;
2012  }
2013 
2014  if (sign)
2015  res = -res;
2016 
2017  return res;
2018 }
#define K_VERS_1_0
ReadBytePtrType ReadBytePtr
char sign
Definition: informix.c:668

◆ ReadOffset()

int ReadOffset ( ArchiveHandle AH,
pgoff_t o 
)

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

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

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

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

2041 {
2042  char *buf;
2043  int l;
2044 
2045  l = ReadInt(AH);
2046  if (l < 0)
2047  buf = NULL;
2048  else
2049  {
2050  buf = (char *) pg_malloc(l + 1);
2051  AH->ReadBufPtr(AH, (void *) buf, l);
2052 
2053  buf[l] = '\0';
2054  }
2055 
2056  return buf;
2057 }
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:68

◆ ReadToc()

void ReadToc ( ArchiveHandle AH)

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

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

References pg_free(), and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4242 {
4243  pg_free(ready_list->tes);
4244 }
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 4228 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().

4229 {
4230  ready_list->tes = (TocEntry **)
4231  pg_malloc(tocCount * sizeof(TocEntry *));
4232  ready_list->first_te = 0;
4233  ready_list->last_te = -1;
4234  ready_list->sorted = false;
4235 }
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 4248 of file pg_backup_archiver.c.

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

Referenced by move_to_ready_list(), and reduce_dependencies().

4249 {
4250  ready_list->tes[++ready_list->last_te] = te;
4251  /* List is (probably) not sorted anymore. */
4252  ready_list->sorted = false;
4253 }

◆ ready_list_remove()

static void ready_list_remove ( ParallelReadyList ready_list,
int  i 
)
static

Definition at line 4257 of file pg_backup_archiver.c.

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

Referenced by pop_next_work_item().

4258 {
4259  int f = ready_list->first_te;
4260 
4261  Assert(i >= f && i <= ready_list->last_te);
4262 
4263  /*
4264  * In the typical case where the item to be removed is the first ready
4265  * entry, we need only increment first_te to remove it. Otherwise, move
4266  * the entries before it to compact the list. (This preserves sortedness,
4267  * if any.) We could alternatively move the entries after i, but there
4268  * are typically many more of those.
4269  */
4270  if (i > f)
4271  {
4272  TocEntry **first_te_ptr = &ready_list->tes[f];
4273 
4274  memmove(first_te_ptr + 1, first_te_ptr, (i - f) * sizeof(TocEntry *));
4275  }
4276  ready_list->first_te++;
4277 }
#define Assert(condition)
Definition: c.h:745
int i

◆ ready_list_sort()

static void ready_list_sort ( ParallelReadyList ready_list)
static

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

4282 {
4283  if (!ready_list->sorted)
4284  {
4285  int n = ready_list->last_te - ready_list->first_te + 1;
4286 
4287  if (n > 1)
4288  qsort(ready_list->tes + ready_list->first_te, n,
4289  sizeof(TocEntry *),
4291  ready_list->sorted = true;
4292  }
4293 }
static int TocEntrySizeCompare(const void *p1, const void *p2)
#define qsort(a, b, c, d)
Definition: port.h:475

◆ reduce_dependencies()

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

Definition at line 4710 of file pg_backup_archiver.c.

References _tocEntryRestorePass(), Assert, _tocEntry::depCount, _tocEntry::dumpId, i, _tocEntry::nRevDeps, pending_list_remove(), _tocEntry::pending_prev, pg_log_debug, ready_list_insert(), _archiveHandle::restorePass, _tocEntry::revDeps, and _archiveHandle::tocsByDumpId.

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

4712 {
4713  int i;
4714 
4715  pg_log_debug("reducing dependencies for %d", te->dumpId);
4716 
4717  for (i = 0; i < te->nRevDeps; i++)
4718  {
4719  TocEntry *otherte = AH->tocsByDumpId[te->revDeps[i]];
4720 
4721  Assert(otherte->depCount > 0);
4722  otherte->depCount--;
4723 
4724  /*
4725  * It's ready if it has no remaining dependencies, and it belongs in
4726  * the current restore pass, and it is currently a member of the
4727  * pending list (that check is needed to prevent double restore in
4728  * some cases where a list-file forces out-of-order restoring).
4729  * However, if ready_list == NULL then caller doesn't want any list
4730  * memberships changed.
4731  */
4732  if (otherte->depCount == 0 &&
4733  _tocEntryRestorePass(otherte) == AH->restorePass &&
4734  otherte->pending_prev != NULL &&
4735  ready_list != NULL)
4736  {
4737  /* Remove it from pending list ... */
4738  pending_list_remove(otherte);
4739  /* ... and add to ready_list */
4740  ready_list_insert(ready_list, otherte);
4741  }
4742  }
4743 }
struct _tocEntry * pending_prev
RestorePass restorePass
#define pg_log_debug(...)
Definition: logging.h:92
static RestorePass _tocEntryRestorePass(TocEntry *te)
#define Assert(condition)
Definition: c.h:745