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 void processToastCompressionEntry (ArchiveHandle *AH, TocEntry *te)
 
static int _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)
 
int 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 2203 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().

2206 {
2207  ArchiveHandle *AH;
2208 
2209  pg_log_debug("allocating AH for %s, format %d",
2210  FileSpec ? FileSpec : "(stdio)", fmt);
2211 
2212  AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle));
2213 
2214  AH->version = K_VERS_SELF;
2215 
2216  /* initialize for backwards compatible string processing */
2217  AH->public.encoding = 0; /* PG_SQL_ASCII */
2218  AH->public.std_strings = false;
2219 
2220  /* sql error handling */
2221  AH->public.exit_on_error = true;
2222  AH->public.n_errors = 0;
2223 
2224  AH->archiveDumpVersion = PG_VERSION;
2225 
2226  AH->createDate = time(NULL);
2227 
2228  AH->intSize = sizeof(int);
2229  AH->offSize = sizeof(pgoff_t);
2230  if (FileSpec)
2231  {
2232  AH->fSpec = pg_strdup(FileSpec);
2233 
2234  /*
2235  * Not used; maybe later....
2236  *
2237  * AH->workDir = pg_strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
2238  * i--) if (AH->workDir[i-1] == '/')
2239  */
2240  }
2241  else
2242  AH->fSpec = NULL;
2243 
2244  AH->currUser = NULL; /* unknown */
2245  AH->currSchema = NULL; /* ditto */
2246  AH->currTablespace = NULL; /* ditto */
2247  AH->currTableAm = NULL; /* ditto */
2248 
2249  AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2250 
2251  AH->toc->next = AH->toc;
2252  AH->toc->prev = AH->toc;
2253 
2254  AH->mode = mode;
2255  AH->compression = compression;
2256  AH->dosync = dosync;
2257 
2258  memset(&(AH->sqlparse), 0, sizeof(AH->sqlparse));
2259 
2260  /* Open stdout with no compression for AH output handle */
2261  AH->gzOut = 0;
2262  AH->OF = stdout;
2263 
2264  /*
2265  * On Windows, we need to use binary mode to read/write non-text files,
2266  * which include all archive formats as well as compressed plain text.
2267  * Force stdin/stdout into binary mode if that is what we are using.
2268  */
2269 #ifdef WIN32
2270  if ((fmt != archNull || compression != 0) &&
2271  (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
2272  {
2273  if (mode == archModeWrite)
2274  _setmode(fileno(stdout), O_BINARY);
2275  else
2276  _setmode(fileno(stdin), O_BINARY);
2277  }
2278 #endif
2279 
2280  AH->SetupWorkerPtr = setupWorkerPtr;
2281 
2282  if (fmt == archUnknown)
2283  AH->format = _discoverArchiveFormat(AH);
2284  else
2285  AH->format = fmt;
2286 
2287  switch (AH->format)
2288  {
2289  case archCustom:
2291  break;
2292 
2293  case archNull:
2294  InitArchiveFmt_Null(AH);
2295  break;
2296 
2297  case archDirectory:
2299  break;
2300 
2301  case archTar:
2302  InitArchiveFmt_Tar(AH);
2303  break;
2304 
2305  default:
2306  fatal("unrecognized file format \"%d\"", fmt);
2307  }
2308 
2309  return AH;
2310 }
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:217
int encoding
Definition: pg_backup.h:206
SetupWorkerPtrType SetupWorkerPtr
#define pgoff_t
Definition: win32_port.h:200
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:216
bool std_strings
Definition: pg_backup.h:207

◆ _becomeOwner()

static void _becomeOwner ( ArchiveHandle AH,
TocEntry te 
)
static

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

3245 {
3246  RestoreOptions *ropt = AH->public.ropt;
3247 
3248  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3249  return;
3250 
3251  _becomeUser(AH, te->owner);
3252 }
RestoreOptions * ropt
Definition: pg_backup.h:192
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 3220 of file pg_backup_archiver.c.

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

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

3221 {
3222  if (!user)
3223  user = ""; /* avoid null pointers */
3224 
3225  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3226  return; /* no need to do anything */
3227 
3228  _doSetSessionAuth(AH, user);
3229 
3230  /*
3231  * NOTE: currUser keeps track of what the imaginary session user in our
3232  * script is
3233  */
3234  if (AH->currUser)
3235  free(AH->currUser);
3236  AH->currUser = pg_strdup(user);
3237 }
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 980 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().

981 {
982  RestoreOptions *ropt = AH->public.ropt;
983 
984  /* This hack is only needed in a data-only restore */
985  if (!ropt->dataOnly || !ropt->disable_triggers)
986  return;
987 
988  pg_log_info("disabling triggers for %s", te->tag);
989 
990  /*
991  * Become superuser if possible, since they are the only ones who can
992  * disable constraint triggers. If -S was not given, assume the initial
993  * user identity is a superuser. (XXX would it be better to become the
994  * table owner?)
995  */
996  _becomeUser(AH, ropt->superuser);
997 
998  /*
999  * Disable them.
1000  */
1001  ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
1002  fmtQualifiedId(te->namespace, te->tag));
1003 }
RestoreOptions * ropt
Definition: pg_backup.h:192
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 2062 of file pg_backup_archiver.c.

References archCustom, archDirectory, archTar, buf, fatal, _archiveHandle::format, free, _archiveHandle::fSpec, isValidTarHeader(), _archiveHandle::lookahead, _archiveHandle::lookaheadLen, _archiveHandle::lookaheadPos, _archiveHandle::lookaheadSize, MAXPGPATH, PG_BINARY_R, pg_log_debug, pg_malloc0(), READ_ERROR_EXIT, _archiveHandle::readHeader, S_ISDIR, S_ISREG, sig, snprintf, stat::st_mode, stat, TEXT_DUMP_HEADER, and TEXT_DUMPALL_HEADER.

Referenced by _allocAH().

2063 {
2064  FILE *fh;
2065  char sig[6]; /* More than enough */
2066  size_t cnt;
2067  int wantClose = 0;
2068 
2069  pg_log_debug("attempting to ascertain archive format");
2070 
2071  if (AH->lookahead)
2072  free(AH->lookahead);
2073 
2074  AH->readHeader = 0;
2075  AH->lookaheadSize = 512;
2076  AH->lookahead = pg_malloc0(512);
2077  AH->lookaheadLen = 0;
2078  AH->lookaheadPos = 0;
2079 
2080  if (AH->fSpec)
2081  {
2082  struct stat st;
2083 
2084  wantClose = 1;
2085 
2086  /*
2087  * Check if the specified archive is a directory. If so, check if
2088  * there's a "toc.dat" (or "toc.dat.gz") file in it.
2089  */
2090  if (stat(AH->fSpec, &st) == 0 && S_ISDIR(st.st_mode))
2091  {
2092  char buf[MAXPGPATH];
2093 
2094  if (snprintf(buf, MAXPGPATH, "%s/toc.dat", AH->fSpec) >= MAXPGPATH)
2095  fatal("directory name too long: \"%s\"",
2096  AH->fSpec);
2097  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2098  {
2099  AH->format = archDirectory;
2100  return AH->format;
2101  }
2102 
2103 #ifdef HAVE_LIBZ
2104  if (snprintf(buf, MAXPGPATH, "%s/toc.dat.gz", AH->fSpec) >= MAXPGPATH)
2105  fatal("directory name too long: \"%s\"",
2106  AH->fSpec);
2107  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2108  {
2109  AH->format = archDirectory;
2110  return AH->format;
2111  }
2112 #endif
2113  fatal("directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)",
2114  AH->fSpec);
2115  fh = NULL; /* keep compiler quiet */
2116  }
2117  else
2118  {
2119  fh = fopen(AH->fSpec, PG_BINARY_R);
2120  if (!fh)
2121  fatal("could not open input file \"%s\": %m", AH->fSpec);
2122  }
2123  }
2124  else
2125  {
2126  fh = stdin;
2127  if (!fh)
2128  fatal("could not open input file: %m");
2129  }
2130 
2131  if ((cnt = fread(sig, 1, 5, fh)) != 5)
2132  {
2133  if (ferror(fh))
2134  fatal("could not read input file: %m");
2135  else
2136  fatal("input file is too short (read %lu, expected 5)",
2137  (unsigned long) cnt);
2138  }
2139 
2140  /* Save it, just in case we need it later */
2141  memcpy(&AH->lookahead[0], sig, 5);
2142  AH->lookaheadLen = 5;
2143 
2144  if (strncmp(sig, "PGDMP", 5) == 0)
2145  {
2146  /* It's custom format, stop here */
2147  AH->format = archCustom;
2148  AH->readHeader = 1;
2149  }
2150  else
2151  {
2152  /*
2153  * *Maybe* we have a tar archive format file or a text dump ... So,
2154  * read first 512 byte header...
2155  */
2156  cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
2157  /* read failure is checked below */
2158  AH->lookaheadLen += cnt;
2159 
2160  if (AH->lookaheadLen >= strlen(TEXT_DUMPALL_HEADER) &&
2161  (strncmp(AH->lookahead, TEXT_DUMP_HEADER, strlen(TEXT_DUMP_HEADER)) == 0 ||
2162  strncmp(AH->lookahead, TEXT_DUMPALL_HEADER, strlen(TEXT_DUMPALL_HEADER)) == 0))
2163  {
2164  /*
2165  * looks like it's probably a text format dump. so suggest they
2166  * try psql
2167  */
2168  fatal("input file appears to be a text format dump. Please use psql.");
2169  }
2170 
2171  if (AH->lookaheadLen != 512)
2172  {
2173  if (feof(fh))
2174  fatal("input file does not appear to be a valid archive (too short?)");
2175  else
2176  READ_ERROR_EXIT(fh);
2177  }
2178 
2179  if (!isValidTarHeader(AH->lookahead))
2180  fatal("input file does not appear to be a valid archive");
2181 
2182  AH->format = archTar;
2183  }
2184 
2185  /* Close the file if we opened it */
2186  if (wantClose)
2187  {
2188  if (fclose(fh) != 0)
2189  fatal("could not close input file: %m");
2190  /* Forget lookahead, since we'll re-read header after re-opening */
2191  AH->readHeader = 0;
2192  AH->lookaheadLen = 0;
2193  }
2194 
2195  return AH->format;
2196 }
#define TEXT_DUMP_HEADER
bool isValidTarHeader(char *header)
#define PG_BINARY_R
Definition: c.h:1273
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define pg_log_debug(...)
Definition: logging.h:92
#define MAXPGPATH
static char * buf
Definition: pg_test_fsync.c:68
#define S_ISREG(m)
Definition: win32_port.h:319
ArchiveFormat format
#define TEXT_DUMPALL_HEADER
static int sig
Definition: pg_ctl.c:84
#define free(a)
Definition: header.h:65
#define fatal(...)
#define S_ISDIR(m)
Definition: win32_port.h:316
#define READ_ERROR_EXIT(fd)
#define snprintf
Definition: port.h:216
#define stat
Definition: win32_port.h:275

◆ _doSetFixedOutputState()

static void _doSetFixedOutputState ( ArchiveHandle AH)
static

Definition at line 3079 of file pg_backup_archiver.c.

References ahprintf(), Archive::default_toast_compression, _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().

3080 {
3081  RestoreOptions *ropt = AH->public.ropt;
3082 
3083  /*
3084  * Disable timeouts to allow for slow commands, idle parallel workers, etc
3085  */
3086  ahprintf(AH, "SET statement_timeout = 0;\n");
3087  ahprintf(AH, "SET lock_timeout = 0;\n");
3088  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
3089 
3090  /* Select the correct character set encoding */
3091  ahprintf(AH, "SET client_encoding = '%s';\n",
3093 
3094  /* Select the correct string literal syntax */
3095  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
3096  AH->public.std_strings ? "on" : "off");
3097 
3098  /* Select the role to be used during restore */
3099  if (ropt && ropt->use_role)
3100  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
3101 
3102  /* Select the dump-time search_path */
3103  if (AH->public.searchpath)
3104  ahprintf(AH, "%s", AH->public.searchpath);
3105 
3106  /* Select the dump-time default_toast_compression */
3108  ahprintf(AH, "SET default_toast_compression = '%s';\n",
3110 
3111  /* Make sure function checking is disabled */
3112  ahprintf(AH, "SET check_function_bodies = false;\n");
3113 
3114  /* Ensure that all valid XML data will be accepted */
3115  ahprintf(AH, "SET xmloption = content;\n");
3116 
3117  /* Avoid annoying notices etc */
3118  ahprintf(AH, "SET client_min_messages = warning;\n");
3119  if (!AH->public.std_strings)
3120  ahprintf(AH, "SET escape_string_warning = off;\n");
3121 
3122  /* Adjust row-security state */
3123  if (ropt && ropt->enable_row_security)
3124  ahprintf(AH, "SET row_security = on;\n");
3125  else
3126  ahprintf(AH, "SET row_security = off;\n");
3127 
3128  ahprintf(AH, "\n");
3129 }
RestoreOptions * ropt
Definition: pg_backup.h:192
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:206
int enable_row_security
Definition: pg_backup.h:134
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * default_toast_compression
Definition: pg_backup.h:211
char * searchpath
Definition: pg_backup.h:210
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
bool std_strings
Definition: pg_backup.h:207

◆ _doSetSessionAuth()

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

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

3138 {
3140 
3141  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3142 
3143  /*
3144  * SQL requires a string literal here. Might as well be correct.
3145  */
3146  if (user && *user)
3147  appendStringLiteralAHX(cmd, user, AH);
3148  else
3149  appendPQExpBufferStr(cmd, "DEFAULT");
3150  appendPQExpBufferChar(cmd, ';');
3151 
3152  if (RestoringToDB(AH))
3153  {
3154  PGresult *res;
3155 
3156  res = PQexec(AH->connection, cmd->data);
3157 
3158  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3159  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3160  fatal("could not set session user to \"%s\": %s",
3162 
3163  PQclear(res);
3164  }
3165  else
3166  ahprintf(AH, "%s\n\n", cmd->data);
3167 
3168  destroyPQExpBuffer(cmd);
3169 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6735
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
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:680
#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:2142

◆ _enableTriggersIfNecessary()

static void _enableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

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

1007 {
1008  RestoreOptions *ropt = AH->public.ropt;
1009 
1010  /* This hack is only needed in a data-only restore */
1011  if (!ropt->dataOnly || !ropt->disable_triggers)
1012  return;
1013 
1014  pg_log_info("enabling triggers for %s", te->tag);
1015 
1016  /*
1017  * Become superuser if possible, since they are the only ones who can
1018  * disable constraint triggers. If -S was not given, assume the initial
1019  * user identity is a superuser. (XXX would it be better to become the
1020  * table owner?)
1021  */
1022  _becomeUser(AH, ropt->superuser);
1023 
1024  /*
1025  * Enable them.
1026  */
1027  ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
1028  fmtQualifiedId(te->namespace, te->tag));
1029 }
RestoreOptions * ropt
Definition: pg_backup.h:192
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 3418 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().

3419 {
3420  const char *type = te->desc;
3421 
3422  /* Use ALTER TABLE for views and sequences */
3423  if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0 ||
3424  strcmp(type, "MATERIALIZED VIEW") == 0)
3425  type = "TABLE";
3426 
3427  /* objects that don't require special decoration */
3428  if (strcmp(type, "COLLATION") == 0 ||
3429  strcmp(type, "CONVERSION") == 0 ||
3430  strcmp(type, "DOMAIN") == 0 ||
3431  strcmp(type, "TABLE") == 0 ||
3432  strcmp(type, "TYPE") == 0 ||
3433  strcmp(type, "FOREIGN TABLE") == 0 ||
3434  strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
3435  strcmp(type, "TEXT SEARCH CONFIGURATION") == 0 ||
3436  strcmp(type, "STATISTICS") == 0 ||
3437  /* non-schema-specified objects */
3438  strcmp(type, "DATABASE") == 0 ||
3439  strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
3440  strcmp(type, "SCHEMA") == 0 ||
3441  strcmp(type, "EVENT TRIGGER") == 0 ||
3442  strcmp(type, "FOREIGN DATA WRAPPER") == 0 ||
3443  strcmp(type, "SERVER") == 0 ||
3444  strcmp(type, "PUBLICATION") == 0 ||
3445  strcmp(type, "SUBSCRIPTION") == 0 ||
3446  strcmp(type, "USER MAPPING") == 0)
3447  {
3448  appendPQExpBuffer(buf, "%s ", type);
3449  if (te->namespace && *te->namespace)
3450  appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));
3451  appendPQExpBufferStr(buf, fmtId(te->tag));
3452  return;
3453  }
3454 
3455  /* BLOBs just have a name, but it's numeric so must not use fmtId */
3456  if (strcmp(type, "BLOB") == 0)
3457  {
3458  appendPQExpBuffer(buf, "LARGE OBJECT %s", te->tag);
3459  return;
3460  }
3461 
3462  /*
3463  * These object types require additional decoration. Fortunately, the
3464  * information needed is exactly what's in the DROP command.
3465  */
3466  if (strcmp(type, "AGGREGATE") == 0 ||
3467  strcmp(type, "FUNCTION") == 0 ||
3468  strcmp(type, "OPERATOR") == 0 ||
3469  strcmp(type, "OPERATOR CLASS") == 0 ||
3470  strcmp(type, "OPERATOR FAMILY") == 0 ||
3471  strcmp(type, "PROCEDURE") == 0)
3472  {
3473  /* Chop "DROP " off the front and make a modifiable copy */
3474  char *first = pg_strdup(te->dropStmt + 5);
3475  char *last;
3476 
3477  /* point to last character in string */
3478  last = first + strlen(first) - 1;
3479 
3480  /* Strip off any ';' or '\n' at the end */
3481  while (last >= first && (*last == '\n' || *last == ';'))
3482  last--;
3483  *(last + 1) = '\0';
3484 
3485  appendPQExpBufferStr(buf, first);
3486 
3487  free(first);
3488  return;
3489  }
3490 
3491  pg_log_warning("don't know how to set owner for object type \"%s\"",
3492  type);
3493 }
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 1794 of file pg_backup_archiver.c.

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

Referenced by SortTocFromFile().

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

◆ _printTocEntry()

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

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

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

3181 {
3182  if (RestoringToDB(AH))
3184  else
3185  {
3186  PQExpBufferData connectbuf;
3187 
3188  initPQExpBuffer(&connectbuf);
3189  appendPsqlMetaConnect(&connectbuf, dbname);
3190  ahprintf(AH, "%s\n", connectbuf.data);
3191  termPQExpBuffer(&connectbuf);
3192  }
3193 
3194  /*
3195  * NOTE: currUser keeps track of what the imaginary session user in our
3196  * script is. It's now effectively reset to the original userID.
3197  */
3198  if (AH->currUser)
3199  free(AH->currUser);
3200  AH->currUser = NULL;
3201 
3202  /* don't assume we still know the output schema, tablespace, etc either */
3203  if (AH->currSchema)
3204  free(AH->currSchema);
3205  AH->currSchema = NULL;
3206  if (AH->currTablespace)
3207  free(AH->currTablespace);
3208  AH->currTablespace = NULL;
3209 
3210  /* re-establish fixed state */
3212 }
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 3260 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().

3261 {
3262  PQExpBuffer qry;
3263 
3264  /*
3265  * If there was a SEARCHPATH TOC entry, we're supposed to just stay with
3266  * that search_path rather than switching to entry-specific paths.
3267  * Otherwise, it's an old archive that will not restore correctly unless
3268  * we set the search_path as it's expecting.
3269  */
3270  if (AH->public.searchpath)
3271  return;
3272 
3273  if (!schemaName || *schemaName == '\0' ||
3274  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3275  return; /* no need to do anything */
3276 
3277  qry = createPQExpBuffer();
3278 
3279  appendPQExpBuffer(qry, "SET search_path = %s",
3280  fmtId(schemaName));
3281  if (strcmp(schemaName, "pg_catalog") != 0)
3282  appendPQExpBufferStr(qry, ", pg_catalog");
3283 
3284  if (RestoringToDB(AH))
3285  {
3286  PGresult *res;
3287 
3288  res = PQexec(AH->connection, qry->data);
3289 
3290  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3292  "could not set search_path to \"%s\": %s",
3293  schemaName, PQerrorMessage(AH->connection));
3294 
3295  PQclear(res);
3296  }
3297  else
3298  ahprintf(AH, "%s;\n\n", qry->data);
3299 
3300  if (AH->currSchema)
3301  free(AH->currSchema);
3302  AH->currSchema = pg_strdup(schemaName);
3303 
3304  destroyPQExpBuffer(qry);
3305 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6735
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:3097
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:210
void PQclear(PGresult *res)
Definition: fe-exec.c:680
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2142

◆ _selectTableAccessMethod()

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

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

3374 {
3375  PQExpBuffer cmd;
3376  const char *want,
3377  *have;
3378 
3379  have = AH->currTableAm;
3380  want = tableam;
3381 
3382  if (!want)
3383  return;
3384 
3385  if (have && strcmp(want, have) == 0)
3386  return;
3387 
3388  cmd = createPQExpBuffer();
3389  appendPQExpBuffer(cmd, "SET default_table_access_method = %s;", fmtId(want));
3390 
3391  if (RestoringToDB(AH))
3392  {
3393  PGresult *res;
3394 
3395  res = PQexec(AH->connection, cmd->data);
3396 
3397  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3399  "could not set default_table_access_method: %s",
3400  PQerrorMessage(AH->connection));
3401 
3402  PQclear(res);
3403  }
3404  else
3405  ahprintf(AH, "%s\n\n", cmd->data);
3406 
3407  destroyPQExpBuffer(cmd);
3408 
3409  AH->currTableAm = pg_strdup(want);
3410 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6735
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:3097
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:680
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2142

◆ _selectTablespace()

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

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

3313 {
3314  RestoreOptions *ropt = AH->public.ropt;
3315  PQExpBuffer qry;
3316  const char *want,
3317  *have;
3318 
3319  /* do nothing in --no-tablespaces mode */
3320  if (ropt->noTablespace)
3321  return;
3322 
3323  have = AH->currTablespace;
3324  want = tablespace;
3325 
3326  /* no need to do anything for non-tablespace object */
3327  if (!want)
3328  return;
3329 
3330  if (have && strcmp(want, have) == 0)
3331  return; /* no need to do anything */
3332 
3333  qry = createPQExpBuffer();
3334 
3335  if (strcmp(want, "") == 0)
3336  {
3337  /* We want the tablespace to be the database's default */
3338  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3339  }
3340  else
3341  {
3342  /* We want an explicit tablespace */
3343  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3344  }
3345 
3346  if (RestoringToDB(AH))
3347  {
3348  PGresult *res;
3349 
3350  res = PQexec(AH->connection, qry->data);
3351 
3352  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3354  "could not set default_tablespace to %s: %s",
3355  fmtId(want), PQerrorMessage(AH->connection));
3356 
3357  PQclear(res);
3358  }
3359  else
3360  ahprintf(AH, "%s;\n\n", qry->data);
3361 
3362  if (AH->currTablespace)
3363  free(AH->currTablespace);
3364  AH->currTablespace = pg_strdup(want);
3365 
3366  destroyPQExpBuffer(qry);
3367 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6735
RestoreOptions * ropt
Definition: pg_backup.h:192
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:3097
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * tablespace
Definition: pgbench.c:224
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:680
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2142

◆ _tocEntryIsACL()

static bool _tocEntryIsACL ( TocEntry te)
static

Definition at line 3064 of file pg_backup_archiver.c.

References _tocEntry::desc.

Referenced by _printTocEntry(), and _tocEntryRequired().

3065 {
3066  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3067  if (strcmp(te->desc, "ACL") == 0 ||
3068  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3069  strcmp(te->desc, "DEFAULT ACL") == 0)
3070  return true;
3071  return false;
3072 }

◆ _tocEntryRequired()

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

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

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

◆ _tocEntryRestorePass()

static RestorePass _tocEntryRestorePass ( TocEntry te)
static

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

3032 {
3033  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3034  if (strcmp(te->desc, "ACL") == 0 ||
3035  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3036  strcmp(te->desc, "DEFAULT ACL") == 0)
3037  return RESTORE_PASS_ACL;
3038  if (strcmp(te->desc, "EVENT TRIGGER") == 0 ||
3039  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0)
3040  return RESTORE_PASS_POST_ACL;
3041 
3042  /*
3043  * Comments need to be emitted in the same pass as their parent objects.
3044  * ACLs haven't got comments, and neither do matview data objects, but
3045  * event triggers do. (Fortunately, event triggers haven't got ACLs, or
3046  * we'd need yet another weird special case.)
3047  */
3048  if (strcmp(te->desc, "COMMENT") == 0 &&
3049  strncmp(te->tag, "EVENT TRIGGER ", 14) == 0)
3050  return RESTORE_PASS_POST_ACL;
3051 
3052  /* All else can be handled in the main pass. */
3053  return RESTORE_PASS_MAIN;
3054 }

◆ ahprintf()

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

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

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

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

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

◆ archprintf()

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

Definition at line 1452 of file pg_backup_archiver.c.

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

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

References WriteData().

Referenced by dumpTableData_insert().

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

◆ buildTocEntryArrays()

static void buildTocEntryArrays ( ArchiveHandle AH)
static

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

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

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3836 {
3837  pgoff_t tpos;
3838 
3839  /* Check that ftello works on this file */
3840  tpos = ftello(fp);
3841  if (tpos < 0)
3842  return false;
3843 
3844  /*
3845  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3846  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3847  * successful no-op even on files that are otherwise unseekable.
3848  */
3849  if (fseeko(fp, tpos, SEEK_SET) != 0)
3850  return false;
3851 
3852  return true;
3853 }
#define pgoff_t
Definition: win32_port.h:200
#define ftello(stream)
Definition: win32_port.h:210
#define fseeko(stream, offset, origin)
Definition: win32_port.h:207

◆ CloneArchive()

ArchiveHandle* CloneArchive ( ArchiveHandle AH)

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

4760 {
4761  ArchiveHandle *clone;
4762 
4763  /* Make a "flat" copy */
4764  clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
4765  memcpy(clone, AH, sizeof(ArchiveHandle));
4766 
4767  /* Handle format-independent fields */
4768  memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse));
4769 
4770  /* The clone will have its own connection, so disregard connection state */
4771  clone->connection = NULL;
4772  clone->connCancel = NULL;
4773  clone->currUser = NULL;
4774  clone->currSchema = NULL;
4775  clone->currTablespace = NULL;
4776 
4777  /* savedPassword must be local in case we change it while connecting */
4778  if (clone->savedPassword)
4779  clone->savedPassword = pg_strdup(clone->savedPassword);
4780 
4781  /* clone has its own error count, too */
4782  clone->public.n_errors = 0;
4783 
4784  /*
4785  * Connect our new clone object to the database, using the same connection
4786  * parameters used for the original connection.
4787  */
4788  ConnectDatabase((Archive *) clone, &clone->public.ropt->cparams, true);
4789 
4790  /* re-establish fixed state */
4791  if (AH->mode == archModeRead)
4792  _doSetFixedOutputState(clone);
4793  /* in write case, setupDumpWorker will fix up connection state */
4794 
4795  /* Let the format-specific code have a chance too */
4796  clone->ClonePtr(clone);
4797 
4798  Assert(clone->connection != NULL);
4799  return clone;
4800 }
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:192
int n_errors
Definition: pg_backup.h:217
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:804
ClonePtrType ClonePtr

◆ CloseArchive()

void CloseArchive ( Archive AHX)

Definition at line 264 of file pg_backup_archiver.c.

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

Referenced by main().

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

References _allocAH().

Referenced by main().

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

◆ DeCloneArchive()

void DeCloneArchive ( ArchiveHandle AH)

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

4809 {
4810  /* Should not have an open database connection */
4811  Assert(AH->connection == NULL);
4812 
4813  /* Clear format-specific state */
4814  AH->DeClonePtr(AH);
4815 
4816  /* Clear state allocated by CloneArchive */
4817  if (AH->sqlparse.curCmd)
4819 
4820  /* Clear any connection-local state */
4821  if (AH->currUser)
4822  free(AH->currUser);
4823  if (AH->currSchema)
4824  free(AH->currSchema);
4825  if (AH->currTablespace)
4826  free(AH->currTablespace);
4827  if (AH->currTableAm)
4828  free(AH->currTableAm);
4829  if (AH->savedPassword)
4830  free(AH->savedPassword);
4831 
4832  free(AH);
4833 }
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:804

◆ dump_lo_buf()

static void dump_lo_buf ( ArchiveHandle AH)
static

Definition at line 1637 of file pg_backup_archiver.c.

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

Referenced by ahwrite(), and EndRestoreBlob().

1638 {
1639  if (AH->connection)
1640  {
1641  int res;
1642 
1643  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1644  pg_log_debug(ngettext("wrote %zu byte of large object data (result = %d)",
1645  "wrote %zu bytes of large object data (result = %d)",
1646  AH->lo_buf_used),
1647  AH->lo_buf_used, res);
1648  /* We assume there are no short writes, only errors */
1649  if (res != AH->lo_buf_used)
1650  warn_or_exit_horribly(AH, "could not write to large object: %s",
1651  PQerrorMessage(AH->connection));
1652  }
1653  else
1654  {
1656 
1658  (const unsigned char *) AH->lo_buf,
1659  AH->lo_buf_used,
1660  AH);
1661 
1662  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1663  AH->writingBlob = 0;
1664  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1665  AH->writingBlob = 1;
1666 
1667  destroyPQExpBuffer(buf);
1668  }
1669  AH->lo_buf_used = 0;
1670 }
#define appendByteaLiteralAHX(buf, str, len, AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6735
void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...)
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:1182
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74

◆ dumpOptionsFromRestoreOptions()

DumpOptions* dumpOptionsFromRestoreOptions ( RestoreOptions ropt)

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

179 {
180  DumpOptions *dopt = NewDumpOptions();
181 
182  /* this is the inverse of what's at the end of pg_dump.c's main() */
183  dopt->cparams.dbname = ropt->cparams.dbname ? pg_strdup(ropt->cparams.dbname) : NULL;
184  dopt->cparams.pgport = ropt->cparams.pgport ? pg_strdup(ropt->cparams.pgport) : NULL;
185  dopt->cparams.pghost = ropt->cparams.pghost ? pg_strdup(ropt->cparams.pghost) : NULL;
186  dopt->cparams.username = ropt->cparams.username ? pg_strdup(ropt->cparams.username) : NULL;
188  dopt->outputClean = ropt->dropSchema;
189  dopt->dataOnly = ropt->dataOnly;
190  dopt->schemaOnly = ropt->schemaOnly;
191  dopt->if_exists = ropt->if_exists;
192  dopt->column_inserts = ropt->column_inserts;
193  dopt->dumpSections = ropt->dumpSections;
194  dopt->aclsSkip = ropt->aclsSkip;
195  dopt->outputSuperuser = ropt->superuser;
196  dopt->outputCreateDB = ropt->createDB;
197  dopt->outputNoOwner = ropt->noOwner;
198  dopt->outputNoTablespaces = ropt->noTablespace;
199  dopt->disable_triggers = ropt->disable_triggers;
200  dopt->use_setsessauth = ropt->use_setsessauth;
202  dopt->dump_inserts = ropt->dump_inserts;
203  dopt->no_comments = ropt->no_comments;
204  dopt->no_publications = ropt->no_publications;
206  dopt->no_subscriptions = ropt->no_subscriptions;
207  dopt->lockWaitTimeout = ropt->lockWaitTimeout;
210  dopt->sequence_data = ropt->sequence_data;
211 
212  return dopt;
213 }
int column_inserts
Definition: pg_backup.h:155
int disable_triggers
Definition: pg_backup.h:165
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:181
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:167
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:172
char * outputSuperuser
Definition: pg_backup.h:179
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:178
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:168
int outputCreateDB
Definition: pg_backup.h:175
int outputClean
Definition: pg_backup.h:174
int no_comments
Definition: pg_backup.h:157
int outputNoTablespaces
Definition: pg_backup.h:166
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 3860 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3861 {
3862  char buf[64];
3863 
3864  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3865  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3866 }
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 1234 of file pg_backup_archiver.c.

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

Referenced by dumpBlobs().

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

◆ EndRestoreBlob()

void EndRestoreBlob ( ArchiveHandle AH,
Oid  oid 
)

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

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

◆ EndRestoreBlobs()

void EndRestoreBlobs ( ArchiveHandle AH)

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

1272 {
1273  RestoreOptions *ropt = AH->public.ropt;
1274 
1275  if (!ropt->single_txn)
1276  {
1277  if (AH->connection)
1278  CommitTransaction(&AH->public);
1279  else
1280  ahprintf(AH, "COMMIT;\n\n");
1281  }
1282 
1283  pg_log_info(ngettext("restored %d large object",
1284  "restored %d large objects",
1285  AH->blobCount),
1286  AH->blobCount);
1287 }
RestoreOptions * ropt
Definition: pg_backup.h:192
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:1182
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 4456 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().

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

References buildTocEntryArrays(), and _archiveHandle::tocsByDumpId.

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

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

◆ has_lock_conflicts()

static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 4147 of file pg_backup_archiver.c.

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

Referenced by pop_next_work_item().

4148 {
4149  int j,
4150  k;
4151 
4152  for (j = 0; j < te1->nLockDeps; j++)
4153  {
4154  for (k = 0; k < te2->nDeps; k++)
4155  {
4156  if (te1->lockDeps[j] == te2->dependencies[k])
4157  return true;
4158  }
4159  }
4160  return false;
4161 }
DumpId * lockDeps
DumpId * dependencies

◆ identify_locking_dependencies()

static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

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

4621 {
4622  DumpId *lockids;
4623  int nlockids;
4624  int i;
4625 
4626  /*
4627  * We only care about this for POST_DATA items. PRE_DATA items are not
4628  * run in parallel, and DATA items are all independent by assumption.
4629  */
4630  if (te->section != SECTION_POST_DATA)
4631  return;
4632 
4633  /* Quick exit if no dependencies at all */
4634  if (te->nDeps == 0)
4635  return;
4636 
4637  /*
4638  * Most POST_DATA items are ALTER TABLEs or some moral equivalent of that,
4639  * and hence require exclusive lock. However, we know that CREATE INDEX
4640  * does not. (Maybe someday index-creating CONSTRAINTs will fall in that
4641  * category too ... but today is not that day.)
4642  */
4643  if (strcmp(te->desc, "INDEX") == 0)
4644  return;
4645 
4646  /*
4647  * We assume the entry requires exclusive lock on each TABLE or TABLE DATA
4648  * item listed among its dependencies. Originally all of these would have
4649  * been TABLE items, but repoint_table_dependencies would have repointed
4650  * them to the TABLE DATA items if those are present (which they might not
4651  * be, eg in a schema-only dump). Note that all of the entries we are
4652  * processing here are POST_DATA; otherwise there might be a significant
4653  * difference between a dependency on a table and a dependency on its
4654  * data, so that closer analysis would be needed here.
4655  */
4656  lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
4657  nlockids = 0;
4658  for (i = 0; i < te->nDeps; i++)
4659  {
4660  DumpId depid = te->dependencies[i];
4661 
4662  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL &&
4663  ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) ||
4664  strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0))
4665  lockids[nlockids++] = depid;
4666  }
4667 
4668  if (nlockids == 0)
4669  {
4670  free(lockids);
4671  return;
4672  }
4673 
4674  te->lockDeps = pg_realloc(lockids, nlockids * sizeof(DumpId));
4675  te->nLockDeps = nlockids;
4676 }
int DumpId
Definition: pg_backup.h:245
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 4739 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().

4740 {
4741  pg_log_info("table \"%s\" could not be created, will not restore its data",
4742  te->tag);
4743 
4744  if (AH->tableDataId[te->dumpId] != 0)
4745  {
4746  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4747 
4748  ted->reqs = 0;
4749  }
4750 }
struct _tocEntry ** tocsByDumpId
#define pg_log_info(...)
Definition: logging.h:88

◆ InitDumpOptions()

void InitDumpOptions ( DumpOptions opts)

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

165 {
166  memset(opts, 0, sizeof(DumpOptions));
167  /* set any fields that shouldn't default to zeroes */
168  opts->include_everything = true;
171 }
trivalue promptPassword
Definition: pg_backup.h:69
bool include_everything
Definition: pg_backup.h:172
ConnParams cparams
Definition: pg_backup.h:141
int dumpSections
Definition: pg_backup.h:148
#define DUMP_UNSECTIONED

◆ mark_create_done()

static void mark_create_done ( ArchiveHandle AH,
TocEntry te 
)
static

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

4725 {
4726  if (AH->tableDataId[te->dumpId] != 0)
4727  {
4728  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4729 
4730  ted->created = true;
4731  }
4732 }
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 2383 of file pg_backup_archiver.c.

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

Referenced by WriteDataChunks().

2387 {
2388  pg_log_info("finished item %d %s %s",
2389  te->dumpId, te->desc, te->tag);
2390 
2391  if (status != 0)
2392  fatal("worker process failed: exit code %d",
2393  status);
2394 }
#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 4415 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().

4419 {
4420  ParallelReadyList *ready_list = (ParallelReadyList *) callback_data;
4421 
4422  pg_log_info("finished item %d %s %s",
4423  te->dumpId, te->desc, te->tag);
4424 
4425  if (status == WORKER_CREATE_DONE)
4426  mark_create_done(AH, te);
4427  else if (status == WORKER_INHIBIT_DATA)
4428  {
4430  AH->public.n_errors++;
4431  }
4432  else if (status == WORKER_IGNORED_ERRORS)
4433  AH->public.n_errors++;
4434  else if (status != 0)
4435  fatal("worker process failed: exit code %d",
4436  status);
4437 
4438  reduce_dependencies(AH, te, ready_list);
4439 }
#define WORKER_CREATE_DONE
int n_errors
Definition: pg_backup.h:217
#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 4300 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().

4303 {
4304  TocEntry *te;
4305  TocEntry *next_te;
4306 
4307  for (te = pending_list->pending_next; te != pending_list; te = next_te)
4308  {
4309  /* must save list link before possibly removing te from list */
4310  next_te = te->pending_next;
4311 
4312  if (te->depCount == 0 &&
4313  _tocEntryRestorePass(te) == pass)
4314  {
4315  /* Remove it from pending_list ... */
4316  pending_list_remove(te);
4317  /* ... and add to ready_list */
4318  ready_list_insert(ready_list, te);
4319  }
4320  }
4321 }
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 152 of file pg_backup_archiver.c.

References InitDumpOptions(), opts, and pg_malloc().

Referenced by dumpOptionsFromRestoreOptions().

153 {
155 
156  InitDumpOptions(opts);
157  return opts;
158 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
static AmcheckOptions opts
Definition: pg_amcheck.c:110
void InitDumpOptions(DumpOptions *opts)

◆ NewRestoreOptions()

RestoreOptions* NewRestoreOptions ( void  )

Definition at line 965 of file pg_backup_archiver.c.

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

Referenced by _CloseArchive(), and main().

966 {
968 
969  opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions));
970 
971  /* set any fields that shouldn't default to zeroes */
972  opts->format = archUnknown;
975 
976  return opts;
977 }
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
static AmcheckOptions opts
Definition: pg_amcheck.c:110
#define DUMP_UNSECTIONED

◆ OpenArchive()

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

Definition at line 255 of file pg_backup_archiver.c.

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

Referenced by main().

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

4393 {
4394  int status;
4395 
4396  Assert(AH->connection != NULL);
4397 
4398  /* Count only errors associated with this TOC entry */
4399  AH->public.n_errors = 0;
4400 
4401  /* Restore the TOC item */
4402  status = restore_toc_entry(AH, te, true);
4403 
4404  return status;
4405 }
int n_errors
Definition: pg_backup.h:217
static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
#define Assert(condition)
Definition: c.h:804
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 4179 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_prefork().

4180 {
4181  te->pending_prev = l->pending_prev;
4182  l->pending_prev->pending_next = te;
4183  l->pending_prev = te;
4184  te->pending_next = l;
4185 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_header_init()

static void pending_list_header_init ( TocEntry l)
static

Definition at line 4172 of file pg_backup_archiver.c.

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

Referenced by RestoreArchive().

4173 {
4174  l->pending_prev = l->pending_next = l;
4175 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_remove()

static void pending_list_remove ( TocEntry te)
static

Definition at line 4189 of file pg_backup_archiver.c.

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

Referenced by move_to_ready_list(), and reduce_dependencies().

4190 {
4193  te->pending_prev = NULL;
4194  te->pending_next = NULL;
4195 }
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 4335 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().

4337 {
4338  /*
4339  * Sort the ready_list so that we'll tackle larger jobs first.
4340  */
4341  ready_list_sort(ready_list);
4342 
4343  /*
4344  * Search the ready_list until we find a suitable item.
4345  */
4346  for (int i = ready_list->first_te; i <= ready_list->last_te; i++)
4347  {
4348  TocEntry *te = ready_list->tes[i];
4349  bool conflicts = false;
4350 
4351  /*
4352  * Check to see if the item would need exclusive lock on something
4353  * that a currently running item also needs lock on, or vice versa. If
4354  * so, we don't want to schedule them together.
4355  */
4356  for (int k = 0; k < pstate->numWorkers; k++)
4357  {
4358  TocEntry *running_te = pstate->te[k];
4359 
4360  if (running_te == NULL)
4361  continue;
4362  if (has_lock_conflicts(te, running_te) ||
4363  has_lock_conflicts(running_te, te))
4364  {
4365  conflicts = true;
4366  break;
4367  }
4368  }
4369 
4370  if (conflicts)
4371  continue;
4372 
4373  /* passed all tests, so this item can run */
4374  ready_list_remove(ready_list, i);
4375  return te;
4376  }
4377 
4378  pg_log_debug("no item ready");
4379  return NULL;
4380 }
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 1116 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().

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

◆ ProcessArchiveRestoreOptions()

void ProcessArchiveRestoreOptions ( Archive AHX)

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

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

◆ processEncodingEntry()

static void processEncodingEntry ( ArchiveHandle AH,
TocEntry te 
)
static

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

2648 {
2649  /* te->defn should have the form SET client_encoding = 'foo'; */
2650  char *defn = pg_strdup(te->defn);
2651  char *ptr1;
2652  char *ptr2 = NULL;
2653  int encoding;
2654 
2655  ptr1 = strchr(defn, '\'');
2656  if (ptr1)
2657  ptr2 = strchr(++ptr1, '\'');
2658  if (ptr2)
2659  {
2660  *ptr2 = '\0';
2661  encoding = pg_char_to_encoding(ptr1);
2662  if (encoding < 0)
2663  fatal("unrecognized encoding \"%s\"",
2664  ptr1);
2665  AH->public.encoding = encoding;
2666  }
2667  else
2668  fatal("invalid ENCODING item: %s",
2669  te->defn);
2670 
2671  free(defn);
2672 }
int pg_char_to_encoding(const char *name)
Definition: encnames.c:550
int encoding
Definition: pg_backup.h:206
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 2691 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2692 {
2693  /*
2694  * te->defn should contain a command to set search_path. We just copy it
2695  * verbatim for use later.
2696  */
2697  AH->public.searchpath = pg_strdup(te->defn);
2698 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char * searchpath
Definition: pg_backup.h:210

◆ processStdStringsEntry()

static void processStdStringsEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2675 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2676 {
2677  /* te->defn should have the form SET standard_conforming_strings = 'x'; */
2678  char *ptr1;
2679 
2680  ptr1 = strchr(te->defn, '\'');
2681  if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
2682  AH->public.std_strings = true;
2683  else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
2684  AH->public.std_strings = false;
2685  else
2686  fatal("invalid STDSTRINGS item: %s",
2687  te->defn);
2688 }
#define fatal(...)
bool std_strings
Definition: pg_backup.h:207

◆ processToastCompressionEntry()

static void processToastCompressionEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2701 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2702 {
2703  /* te->defn should have the form SET default_toast_compression = 'x'; */
2704  char *defn = pg_strdup(te->defn);
2705  char *ptr1;
2706  char *ptr2 = NULL;
2707 
2708  ptr1 = strchr(defn, '\'');
2709  if (ptr1)
2710  ptr2 = strchr(++ptr1, '\'');
2711  if (ptr2)
2712  {
2713  *ptr2 = '\0';
2715  }
2716  else
2717  fatal("invalid TOASTCOMPRESSION item: %s",
2718  te->defn);
2719 
2720  free(defn);
2721 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char * default_toast_compression
Definition: pg_backup.h:211
#define free(a)
Definition: header.h:65
#define fatal(...)

◆ ReadHead()

void ReadHead ( ArchiveHandle AH)

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

3733 {
3734  char vmaj,
3735  vmin,
3736  vrev;
3737  int fmt;
3738  struct tm crtm;
3739 
3740  /*
3741  * If we haven't already read the header, do so.
3742  *
3743  * NB: this code must agree with _discoverArchiveFormat(). Maybe find a
3744  * way to unify the cases?
3745  */
3746  if (!AH->readHeader)
3747  {
3748  char tmpMag[7];
3749 
3750  AH->ReadBufPtr(AH, tmpMag, 5);
3751 
3752  if (strncmp(tmpMag, "PGDMP", 5) != 0)
3753  fatal("did not find magic string in file header");
3754  }
3755 
3756  vmaj = AH->ReadBytePtr(AH);
3757  vmin = AH->ReadBytePtr(AH);
3758 
3759  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
3760  vrev = AH->ReadBytePtr(AH);
3761  else
3762  vrev = 0;
3763 
3764  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
3765 
3766  if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
3767  fatal("unsupported version (%d.%d) in file header",
3768  vmaj, vmin);
3769 
3770  AH->intSize = AH->ReadBytePtr(AH);
3771  if (AH->intSize > 32)
3772  fatal("sanity check on integer size (%lu) failed",
3773  (unsigned long) AH->intSize);
3774 
3775  if (AH->intSize > sizeof(int))
3776  pg_log_warning("archive was made on a machine with larger integers, some operations might fail");
3777 
3778  if (AH->version >= K_VERS_1_7)
3779  AH->offSize = AH->ReadBytePtr(AH);
3780  else
3781  AH->offSize = AH->intSize;
3782 
3783  fmt = AH->ReadBytePtr(AH);
3784 
3785  if (AH->format != fmt)
3786  fatal("expected format (%d) differs from format found in file (%d)",
3787  AH->format, fmt);
3788 
3789  if (AH->version >= K_VERS_1_2)
3790  {
3791  if (AH->version < K_VERS_1_4)
3792  AH->compression = AH->ReadBytePtr(AH);
3793  else
3794  AH->compression = ReadInt(AH);
3795  }
3796  else
3798 
3799 #ifndef HAVE_LIBZ
3800  if (AH->compression != 0)
3801  pg_log_warning("archive is compressed, but this installation does not support compression -- no data will be available");
3802 #endif
3803 
3804  if (AH->version >= K_VERS_1_4)
3805  {
3806  crtm.tm_sec = ReadInt(AH);
3807  crtm.tm_min = ReadInt(AH);
3808  crtm.tm_hour = ReadInt(AH);
3809  crtm.tm_mday = ReadInt(AH);
3810  crtm.tm_mon = ReadInt(AH);
3811  crtm.tm_year = ReadInt(AH);
3812  crtm.tm_isdst = ReadInt(AH);
3813 
3814  AH->archdbname = ReadStr(AH);
3815 
3816  AH->createDate = mktime(&crtm);
3817 
3818  if (AH->createDate == (time_t) -1)
3819  pg_log_warning("invalid creation date in header");
3820  }
3821 
3822  if (AH->version >= K_VERS_1_10)
3823  {
3824  AH->archiveRemoteVersion = ReadStr(AH);
3825  AH->archiveDumpVersion = ReadStr(AH);
3826  }
3827 }
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 1996 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().

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

◆ ReadOffset()

int ReadOffset ( ArchiveHandle AH,
pgoff_t o 
)

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

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

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

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

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

2491 {
2492  int i;
2493  char *tmp;
2494  DumpId *deps;
2495  int depIdx;
2496  int depSize;
2497  TocEntry *te;
2498 
2499  AH->tocCount = ReadInt(AH);
2500  AH->maxDumpId = 0;
2501 
2502  for (i = 0; i < AH->tocCount; i++)
2503  {
2504  te = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2505  te->dumpId = ReadInt(AH);
2506 
2507  if (te->dumpId > AH->maxDumpId)
2508  AH->maxDumpId = te->dumpId;
2509 
2510  /* Sanity check */
2511  if (te->dumpId <= 0)
2512  fatal("entry ID %d out of range -- perhaps a corrupt TOC",
2513  te->dumpId);
2514 
2515  te->hadDumper = ReadInt(AH);
2516 
2517  if (AH->version >= K_VERS_1_8)
2518  {
2519  tmp = ReadStr(AH);
2520  sscanf(tmp, "%u", &te->catalogId.tableoid);
2521  free(tmp);
2522  }
2523  else
2525  tmp = ReadStr(AH);
2526  sscanf(tmp, "%u", &te->catalogId.oid);
2527  free(tmp);
2528 
2529  te->tag = ReadStr(AH);
2530  te->desc = ReadStr(AH);
2531 
2532  if (AH->version >= K_VERS_1_11)
2533  {
2534  te->section = ReadInt(AH);
2535  }
2536  else
2537  {
2538  /*
2539  * Rules for pre-8.4 archives wherein pg_dump hasn't classified
2540  * the entries into sections. This list need not cover entry
2541  * types added later than 8.4.
2542  */
2543  if (strcmp(te->desc, "COMMENT") == 0 ||
2544  strcmp(te->desc, "ACL") == 0 ||
2545  strcmp(te->desc, "ACL LANGUAGE") == 0)
2546  te->section = SECTION_NONE;
2547  else if (strcmp(te->desc, "TABLE DATA") == 0 ||
2548  strcmp(te->desc, "BLOBS") == 0 ||
2549  strcmp(te->desc, "BLOB COMMENTS") == 0)
2550  te->section = SECTION_DATA;
2551  else if (strcmp(te->desc, "CONSTRAINT") == 0 ||
2552  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
2553  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
2554  strcmp(te->desc, "INDEX") == 0 ||
2555  strcmp(te->desc, "RULE") == 0 ||
2556  strcmp(te->desc, "TRIGGER") == 0)
2557  te->section = SECTION_POST_DATA;
2558  else
2559  te->section = SECTION_PRE_DATA;
2560  }
2561 
2562  te->defn = ReadStr(AH);
2563  te->dropStmt = ReadStr(AH);
2564 
2565  if (AH->version >= K_VERS_1_3)
2566  te->copyStmt = ReadStr(AH);
2567 
2568  if (AH->version >= K_VERS_1_6)
2569  te->namespace = ReadStr(AH);
2570 
2571  if (AH->version >= K_VERS_1_10)
2572  te->tablespace = ReadStr(AH);
2573 
2574  if (AH->version >= K_VERS_1_14)
2575  te->tableam = ReadStr(AH);
2576 
2577  te->owner = ReadStr(AH);
2578  if (AH->version < K_VERS_1_9 || strcmp(ReadStr(AH), "true") == 0)
2579  pg_log_warning("restoring tables WITH OIDS is not supported anymore");
2580 
2581  /* Read TOC entry dependencies */
2582  if (AH->version >= K_VERS_1_5)
2583  {
2584  depSize = 100;
2585  deps = (DumpId *) pg_malloc(sizeof(DumpId) * depSize);
2586  depIdx = 0;
2587  for (;;)
2588  {
2589  tmp = ReadStr(AH);
2590  if (!tmp)
2591  break; /* end of list */
2592  if (depIdx >= depSize)
2593  {
2594  depSize *= 2;
2595  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depSize);
2596  }
2597  sscanf(tmp, "%d", &deps[depIdx]);
2598  free(tmp);
2599  depIdx++;
2600  }
2601 
2602  if (depIdx > 0) /* We have a non-null entry */
2603  {
2604  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depIdx);
2605  te->dependencies = deps;
2606  te->nDeps = depIdx;
2607  }
2608  else
2609  {
2610  free(deps);
2611  te->dependencies = NULL;
2612  te->nDeps = 0;
2613  }
2614  }
2615  else
2616  {
2617  te->dependencies = NULL;
2618  te->nDeps = 0;
2619  }
2620  te->dataLength = 0;
2621 
2622  if (AH->ReadExtraTocPtr)
2623  AH->ReadExtraTocPtr(AH, te);
2624 
2625  pg_log_debug("read TOC entry %d (ID %d) for %s %s",
2626  i, te->dumpId, te->desc, te->tag);
2627 
2628  /* link completed entry into TOC circular list */
2629  te->prev = AH->toc->prev;
2630  AH->toc->prev->next = te;
2631  AH->toc->prev = te;
2632  te->next = AH->toc;
2633 
2634  /* special processing immediately upon read for some items */
2635  if (strcmp(te->desc, "ENCODING") == 0)
2636  processEncodingEntry(AH, te);
2637  else if (strcmp(te->desc, "STDSTRINGS") == 0)
2638  processStdStringsEntry(AH, te);
2639  else if (strcmp(te->desc, "SEARCHPATH") == 0)
2640  processSearchPathEntry(AH, te);
2641  else if (strcmp(te->desc, "TOASTCOMPRESSION") == 0)
2643  }
2644 }
struct _tocEntry * next
static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
int DumpId
Definition: pg_backup.h:245
Oid tableoid
Definition: pg_backup.h:241
static void processToastCompressionEntry(ArchiveHandle *AH, TocEntry *te)
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 4215 of file pg_backup_archiver.c.

References pg_free(), and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4216 {
4217  pg_free(ready_list->tes);
4218 }
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 4202 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().

4203 {
4204  ready_list->tes = (TocEntry **)
4205  pg_malloc(tocCount * sizeof(TocEntry *));
4206  ready_list->first_te = 0;
4207  ready_list->last_te = -1;
4208  ready_list->sorted = false;
4209 }
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 4222 of file pg_backup_archiver.c.

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

Referenced by move_to_ready_list(), and reduce_dependencies().

4223 {
4224  ready_list->tes[++ready_list->last_te] = te;
4225  /* List is (probably) not sorted anymore. */
4226  ready_list->sorted = false;
4227 }

◆ ready_list_remove()

static void ready_list_remove ( ParallelReadyList ready_list,
int  i 
)
static

Definition at line 4231 of file pg_backup_archiver.c.

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

Referenced by pop_next_work_item().

4232 {
4233  int f = ready_list->first_te;
4234 
4235  Assert(i >= f && i <= ready_list->last_te);
4236 
4237  /*
4238  * In the typical case where the item to be removed is the first ready
4239  * entry, we need only increment first_te to remove it. Otherwise, move
4240  * the entries before it to compact the list. (This preserves sortedness,
4241  * if any.) We could alternatively move the entries after i, but there
4242  * are typically many more of those.
4243  */
4244  if (i > f)
4245  {
4246  TocEntry **first_te_ptr = &ready_list->tes[f];
4247 
4248  memmove(first_te_ptr + 1, first_te_ptr, (i - f) * sizeof(TocEntry *));
4249  }
4250  ready_list->first_te++;
4251 }
#define Assert(condition)
Definition: c.h:804
int i

◆ ready_list_sort()

static void ready_list_sort ( ParallelReadyList ready_list)
static

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

4256 {
4257  if (!ready_list->sorted)
4258  {
4259  int n = ready_list->last_te - ready_list->first_te + 1;
4260 
4261  if (n > 1)
4262  qsort(ready_list->tes + ready_list->first_te, n,
4263  sizeof(TocEntry *),
4265  ready_list->sorted = true;
4266  }
4267 }
static int TocEntrySizeCompare(const void *p1, const void *p2)
#define qsort(a, b, c, d)
Definition: port.h:504

◆ reduce_dependencies()

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

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

4686 {
4687  int i;
4688 
4689  pg_log_debug("reducing dependencies for %d", te->dumpId);
4690 
4691  for (i = 0; i < te->nRevDeps; i++)
4692  {
4693  TocEntry *otherte = AH->tocsByDumpId[te->revDeps[i]];
4694 
4695  Assert(otherte->depCount > 0);
4696  otherte->depCount--;
4697 
4698  /*
4699  * It's ready if it has no remaining dependencies, and it belongs in
4700  * the current restore pass, and it is currently a member of the
4701  * pending list (that check is needed to prevent double restore in
4702  * some cases where a list-file forces out-of-order restoring).
4703  * However, if ready_list == NULL then caller doesn't want any list
4704  * memberships changed.
4705  */
4706  if (otherte->depCount == 0 &&
4707  _tocEntryRestorePass(otherte) == AH->restorePass &&
4708  otherte->pending_prev != NULL &&
4709  ready_list != NULL)
4710  {
4711  /* Remove it from pending list ... */
4712  pending_list_remove(otherte);
4713  /* ... and add to ready_list */
4714  ready_list_insert(ready_list, otherte);
4715  }
4716  }
4717 }
struct _tocEntry * pending_prev
RestorePass restorePass