PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_backup_db.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_backup_db.c
4  *
5  * Implements the basic DB functions used by the archiver.
6  *
7  * IDENTIFICATION
8  * src/bin/pg_dump/pg_backup_db.c
9  *
10  *-------------------------------------------------------------------------
11  */
12 #include "postgres_fe.h"
13 
14 #include "dumputils.h"
15 #include "fe_utils/string_utils.h"
16 #include "parallel.h"
17 #include "pg_backup_archiver.h"
18 #include "pg_backup_db.h"
19 #include "pg_backup_utils.h"
20 
21 #include <unistd.h>
22 #include <ctype.h>
23 #ifdef HAVE_TERMIOS_H
24 #include <termios.h>
25 #endif
26 
27 
28 /* translator: this is a module name */
29 static const char *modulename = gettext_noop("archiver (db)");
30 
31 static void _check_database_version(ArchiveHandle *AH);
32 static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *newUser);
33 static void notice_processor(void *arg, const char *message);
34 
35 static void
37 {
38  const char *remoteversion_str;
39  int remoteversion;
40  PGresult *res;
41 
42  remoteversion_str = PQparameterStatus(AH->connection, "server_version");
43  remoteversion = PQserverVersion(AH->connection);
44  if (remoteversion == 0 || !remoteversion_str)
45  exit_horribly(modulename, "could not get server_version from libpq\n");
46 
47  AH->public.remoteVersionStr = pg_strdup(remoteversion_str);
48  AH->public.remoteVersion = remoteversion;
49  if (!AH->archiveRemoteVersion)
51 
52  if (remoteversion != PG_VERSION_NUM
53  && (remoteversion < AH->public.minRemoteVersion ||
54  remoteversion > AH->public.maxRemoteVersion))
55  {
56  write_msg(NULL, "server version: %s; %s version: %s\n",
57  remoteversion_str, progname, PG_VERSION);
58  exit_horribly(NULL, "aborting because of server version mismatch\n");
59  }
60 
61  /*
62  * When running against 9.0 or later, check if we are in recovery mode,
63  * which means we are on a hot standby.
64  */
65  if (remoteversion >= 90000)
66  {
67  res = ExecuteSqlQueryForSingleRow((Archive *) AH, "SELECT pg_catalog.pg_is_in_recovery()");
68 
69  AH->public.isStandby = (strcmp(PQgetvalue(res, 0, 0), "t") == 0);
70  PQclear(res);
71  }
72  else
73  AH->public.isStandby = false;
74 }
75 
76 /*
77  * Reconnect to the server. If dbname is not NULL, use that database,
78  * else the one associated with the archive handle. If username is
79  * not NULL, use that user name, else the one from the handle. If
80  * both the database and the user match the existing connection already,
81  * nothing will be done.
82  *
83  * Returns 1 in any case.
84  */
85 int
86 ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username)
87 {
88  PGconn *newConn;
89  const char *newdbname;
90  const char *newusername;
91 
92  if (!dbname)
93  newdbname = PQdb(AH->connection);
94  else
95  newdbname = dbname;
96 
97  if (!username)
98  newusername = PQuser(AH->connection);
99  else
100  newusername = username;
101 
102  /* Let's see if the request is already satisfied */
103  if (strcmp(newdbname, PQdb(AH->connection)) == 0 &&
104  strcmp(newusername, PQuser(AH->connection)) == 0)
105  return 1;
106 
107  newConn = _connectDB(AH, newdbname, newusername);
108 
109  /* Update ArchiveHandle's connCancel before closing old connection */
110  set_archive_cancel_info(AH, newConn);
111 
112  PQfinish(AH->connection);
113  AH->connection = newConn;
114 
115  return 1;
116 }
117 
118 /*
119  * Connect to the db again.
120  *
121  * Note: it's not really all that sensible to use a single-entry password
122  * cache if the username keeps changing. In current usage, however, the
123  * username never does change, so one savedPassword is sufficient. We do
124  * update the cache on the off chance that the password has changed since the
125  * start of the run.
126  */
127 static PGconn *
128 _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
129 {
131  PGconn *newConn;
132  const char *newdb;
133  const char *newuser;
134  char *password;
135  char passbuf[100];
136  bool new_pass;
137 
138  if (!reqdb)
139  newdb = PQdb(AH->connection);
140  else
141  newdb = reqdb;
142 
143  if (!requser || strlen(requser) == 0)
144  newuser = PQuser(AH->connection);
145  else
146  newuser = requser;
147 
148  ahlog(AH, 1, "connecting to database \"%s\" as user \"%s\"\n",
149  newdb, newuser);
150 
151  password = AH->savedPassword;
152 
153  if (AH->promptPassword == TRI_YES && password == NULL)
154  {
155  simple_prompt("Password: ", passbuf, sizeof(passbuf), false);
156  password = passbuf;
157  }
158 
159  initPQExpBuffer(&connstr);
160  appendPQExpBuffer(&connstr, "dbname=");
161  appendConnStrVal(&connstr, newdb);
162 
163  do
164  {
165  const char *keywords[7];
166  const char *values[7];
167 
168  keywords[0] = "host";
169  values[0] = PQhost(AH->connection);
170  keywords[1] = "port";
171  values[1] = PQport(AH->connection);
172  keywords[2] = "user";
173  values[2] = newuser;
174  keywords[3] = "password";
175  values[3] = password;
176  keywords[4] = "dbname";
177  values[4] = connstr.data;
178  keywords[5] = "fallback_application_name";
179  values[5] = progname;
180  keywords[6] = NULL;
181  values[6] = NULL;
182 
183  new_pass = false;
184  newConn = PQconnectdbParams(keywords, values, true);
185 
186  if (!newConn)
187  exit_horribly(modulename, "failed to reconnect to database\n");
188 
189  if (PQstatus(newConn) == CONNECTION_BAD)
190  {
191  if (!PQconnectionNeedsPassword(newConn))
192  exit_horribly(modulename, "could not reconnect to database: %s",
193  PQerrorMessage(newConn));
194  PQfinish(newConn);
195 
196  if (password)
197  fprintf(stderr, "Password incorrect\n");
198 
199  fprintf(stderr, "Connecting to %s as %s\n",
200  newdb, newuser);
201 
202  if (AH->promptPassword != TRI_NO)
203  {
204  simple_prompt("Password: ", passbuf, sizeof(passbuf), false);
205  password = passbuf;
206  }
207  else
208  exit_horribly(modulename, "connection needs password\n");
209 
210  new_pass = true;
211  }
212  } while (new_pass);
213 
214  /*
215  * We want to remember connection's actual password, whether or not we got
216  * it by prompting. So we don't just store the password variable.
217  */
218  if (PQconnectionUsedPassword(newConn))
219  {
220  if (AH->savedPassword)
221  free(AH->savedPassword);
222  AH->savedPassword = pg_strdup(PQpass(newConn));
223  }
224 
225  termPQExpBuffer(&connstr);
226 
227  /* check for version mismatch */
229 
231 
232  return newConn;
233 }
234 
235 
236 /*
237  * Make a database connection with the given parameters. The
238  * connection handle is returned, the parameters are stored in AHX.
239  * An interactive password prompt is automatically issued if required.
240  *
241  * Note: it's not really all that sensible to use a single-entry password
242  * cache if the username keeps changing. In current usage, however, the
243  * username never does change, so one savedPassword is sufficient.
244  */
245 void
247  const char *dbname,
248  const char *pghost,
249  const char *pgport,
250  const char *username,
251  trivalue prompt_password)
252 {
253  ArchiveHandle *AH = (ArchiveHandle *) AHX;
254  char *password;
255  char passbuf[100];
256  bool new_pass;
257 
258  if (AH->connection)
259  exit_horribly(modulename, "already connected to a database\n");
260 
261  password = AH->savedPassword;
262 
263  if (prompt_password == TRI_YES && password == NULL)
264  {
265  simple_prompt("Password: ", passbuf, sizeof(passbuf), false);
266  password = passbuf;
267  }
268  AH->promptPassword = prompt_password;
269 
270  /*
271  * Start the connection. Loop until we have a password if requested by
272  * backend.
273  */
274  do
275  {
276  const char *keywords[7];
277  const char *values[7];
278 
279  keywords[0] = "host";
280  values[0] = pghost;
281  keywords[1] = "port";
282  values[1] = pgport;
283  keywords[2] = "user";
284  values[2] = username;
285  keywords[3] = "password";
286  values[3] = password;
287  keywords[4] = "dbname";
288  values[4] = dbname;
289  keywords[5] = "fallback_application_name";
290  values[5] = progname;
291  keywords[6] = NULL;
292  values[6] = NULL;
293 
294  new_pass = false;
295  AH->connection = PQconnectdbParams(keywords, values, true);
296 
297  if (!AH->connection)
298  exit_horribly(modulename, "failed to connect to database\n");
299 
300  if (PQstatus(AH->connection) == CONNECTION_BAD &&
302  password == NULL &&
303  prompt_password != TRI_NO)
304  {
305  PQfinish(AH->connection);
306  simple_prompt("Password: ", passbuf, sizeof(passbuf), false);
307  password = passbuf;
308  new_pass = true;
309  }
310  } while (new_pass);
311 
312  /* check to see that the backend connection was successfully made */
313  if (PQstatus(AH->connection) == CONNECTION_BAD)
314  exit_horribly(modulename, "connection to database \"%s\" failed: %s",
315  PQdb(AH->connection) ? PQdb(AH->connection) : "",
317 
318  /*
319  * We want to remember connection's actual password, whether or not we got
320  * it by prompting. So we don't just store the password variable.
321  */
323  {
324  if (AH->savedPassword)
325  free(AH->savedPassword);
327  }
328 
329  /* check for version mismatch */
331 
333 
334  /* arrange for SIGINT to issue a query cancel on this connection */
336 }
337 
338 /*
339  * Close the connection to the database and also cancel off the query if we
340  * have one running.
341  */
342 void
344 {
345  ArchiveHandle *AH = (ArchiveHandle *) AHX;
346  char errbuf[1];
347 
348  if (!AH->connection)
349  return;
350 
351  if (AH->connCancel)
352  {
353  /*
354  * If we have an active query, send a cancel before closing. This is
355  * of no use for a normal exit, but might be helpful during
356  * exit_horribly().
357  */
359  PQcancel(AH->connCancel, errbuf, sizeof(errbuf));
360 
361  /*
362  * Prevent signal handler from sending a cancel after this.
363  */
365  }
366 
367  PQfinish(AH->connection);
368  AH->connection = NULL;
369 }
370 
371 PGconn *
373 {
374  ArchiveHandle *AH = (ArchiveHandle *) AHX;
375 
376  return AH->connection;
377 }
378 
379 static void
380 notice_processor(void *arg, const char *message)
381 {
382  write_msg(NULL, "%s", message);
383 }
384 
385 /* Like exit_horribly(), but with a complaint about a particular query. */
386 static void
387 die_on_query_failure(ArchiveHandle *AH, const char *modulename, const char *query)
388 {
389  write_msg(modulename, "query failed: %s",
391  exit_horribly(modulename, "query was: %s\n", query);
392 }
393 
394 void
395 ExecuteSqlStatement(Archive *AHX, const char *query)
396 {
397  ArchiveHandle *AH = (ArchiveHandle *) AHX;
398  PGresult *res;
399 
400  res = PQexec(AH->connection, query);
401  if (PQresultStatus(res) != PGRES_COMMAND_OK)
402  die_on_query_failure(AH, modulename, query);
403  PQclear(res);
404 }
405 
406 PGresult *
407 ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status)
408 {
409  ArchiveHandle *AH = (ArchiveHandle *) AHX;
410  PGresult *res;
411 
412  res = PQexec(AH->connection, query);
413  if (PQresultStatus(res) != status)
414  die_on_query_failure(AH, modulename, query);
415  return res;
416 }
417 
418 /*
419  * Execute an SQL query and verify that we got exactly one row back.
420  */
421 PGresult *
423 {
424  PGresult *res;
425  int ntups;
426 
427  res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
428 
429  /* Expecting a single result only */
430  ntups = PQntuples(res);
431  if (ntups != 1)
433  ngettext("query returned %d row instead of one: %s\n",
434  "query returned %d rows instead of one: %s\n",
435  ntups),
436  ntups, query);
437 
438  return res;
439 }
440 
441 /*
442  * Convenience function to send a query.
443  * Monitors result to detect COPY statements
444  */
445 static void
446 ExecuteSqlCommand(ArchiveHandle *AH, const char *qry, const char *desc)
447 {
448  PGconn *conn = AH->connection;
449  PGresult *res;
450 
451 #ifdef NOT_USED
452  fprintf(stderr, "Executing: '%s'\n\n", qry);
453 #endif
454  res = PQexec(conn, qry);
455 
456  switch (PQresultStatus(res))
457  {
458  case PGRES_COMMAND_OK:
459  case PGRES_TUPLES_OK:
460  case PGRES_EMPTY_QUERY:
461  /* A-OK */
462  break;
463  case PGRES_COPY_IN:
464  /* Assume this is an expected result */
465  AH->pgCopyIn = true;
466  break;
467  default:
468  /* trouble */
469  warn_or_exit_horribly(AH, modulename, "%s: %s Command was: %s\n",
470  desc, PQerrorMessage(conn), qry);
471  break;
472  }
473 
474  PQclear(res);
475 }
476 
477 
478 /*
479  * Process non-COPY table data (that is, INSERT commands).
480  *
481  * The commands have been run together as one long string for compressibility,
482  * and we are receiving them in bufferloads with arbitrary boundaries, so we
483  * have to locate command boundaries and save partial commands across calls.
484  * All state must be kept in AH->sqlparse, not in local variables of this
485  * routine. We assume that AH->sqlparse was filled with zeroes when created.
486  *
487  * We have to lex the data to the extent of identifying literals and quoted
488  * identifiers, so that we can recognize statement-terminating semicolons.
489  * We assume that INSERT data will not contain SQL comments, E'' literals,
490  * or dollar-quoted strings, so this is much simpler than a full SQL lexer.
491  *
492  * Note: when restoring from a pre-9.0 dump file, this code is also used to
493  * process BLOB COMMENTS data, which has the same problem of containing
494  * multiple SQL commands that might be split across bufferloads. Fortunately,
495  * that data won't contain anything complicated to lex either.
496  */
497 static void
498 ExecuteSimpleCommands(ArchiveHandle *AH, const char *buf, size_t bufLen)
499 {
500  const char *qry = buf;
501  const char *eos = buf + bufLen;
502 
503  /* initialize command buffer if first time through */
504  if (AH->sqlparse.curCmd == NULL)
506 
507  for (; qry < eos; qry++)
508  {
509  char ch = *qry;
510 
511  /* For neatness, we skip any newlines between commands */
512  if (!(ch == '\n' && AH->sqlparse.curCmd->len == 0))
514 
515  switch (AH->sqlparse.state)
516  {
517  case SQL_SCAN: /* Default state == 0, set in _allocAH */
518  if (ch == ';')
519  {
520  /*
521  * We've found the end of a statement. Send it and reset
522  * the buffer.
523  */
525  "could not execute query");
527  }
528  else if (ch == '\'')
529  {
531  AH->sqlparse.backSlash = false;
532  }
533  else if (ch == '"')
534  {
536  }
537  break;
538 
539  case SQL_IN_SINGLE_QUOTE:
540  /* We needn't handle '' specially */
541  if (ch == '\'' && !AH->sqlparse.backSlash)
542  AH->sqlparse.state = SQL_SCAN;
543  else if (ch == '\\' && !AH->public.std_strings)
545  else
546  AH->sqlparse.backSlash = false;
547  break;
548 
549  case SQL_IN_DOUBLE_QUOTE:
550  /* We needn't handle "" specially */
551  if (ch == '"')
552  AH->sqlparse.state = SQL_SCAN;
553  break;
554  }
555  }
556 }
557 
558 
559 /*
560  * Implement ahwrite() for direct-to-DB restore
561  */
562 int
563 ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen)
564 {
565  ArchiveHandle *AH = (ArchiveHandle *) AHX;
566 
567  if (AH->outputKind == OUTPUT_COPYDATA)
568  {
569  /*
570  * COPY data.
571  *
572  * We drop the data on the floor if libpq has failed to enter COPY
573  * mode; this allows us to behave reasonably when trying to continue
574  * after an error in a COPY command.
575  */
576  if (AH->pgCopyIn &&
577  PQputCopyData(AH->connection, buf, bufLen) <= 0)
578  exit_horribly(modulename, "error returned by PQputCopyData: %s",
580  }
581  else if (AH->outputKind == OUTPUT_OTHERDATA)
582  {
583  /*
584  * Table data expressed as INSERT commands; or, in old dump files,
585  * BLOB COMMENTS data (which is expressed as COMMENT ON commands).
586  */
587  ExecuteSimpleCommands(AH, buf, bufLen);
588  }
589  else
590  {
591  /*
592  * General SQL commands; we assume that commands will not be split
593  * across calls.
594  *
595  * In most cases the data passed to us will be a null-terminated
596  * string, but if it's not, we have to add a trailing null.
597  */
598  if (buf[bufLen] == '\0')
599  ExecuteSqlCommand(AH, buf, "could not execute query");
600  else
601  {
602  char *str = (char *) pg_malloc(bufLen + 1);
603 
604  memcpy(str, buf, bufLen);
605  str[bufLen] = '\0';
606  ExecuteSqlCommand(AH, str, "could not execute query");
607  free(str);
608  }
609  }
610 
611  return bufLen;
612 }
613 
614 /*
615  * Terminate a COPY operation during direct-to-DB restore
616  */
617 void
618 EndDBCopyMode(Archive *AHX, const char *tocEntryTag)
619 {
620  ArchiveHandle *AH = (ArchiveHandle *) AHX;
621 
622  if (AH->pgCopyIn)
623  {
624  PGresult *res;
625 
626  if (PQputCopyEnd(AH->connection, NULL) <= 0)
627  exit_horribly(modulename, "error returned by PQputCopyEnd: %s",
629 
630  /* Check command status and return to normal libpq state */
631  res = PQgetResult(AH->connection);
632  if (PQresultStatus(res) != PGRES_COMMAND_OK)
633  warn_or_exit_horribly(AH, modulename, "COPY failed for table \"%s\": %s",
634  tocEntryTag, PQerrorMessage(AH->connection));
635  PQclear(res);
636 
637  /* Do this to ensure we've pumped libpq back to idle state */
638  if (PQgetResult(AH->connection) != NULL)
639  write_msg(NULL, "WARNING: unexpected extra results during COPY of table \"%s\"\n",
640  tocEntryTag);
641 
642  AH->pgCopyIn = false;
643  }
644 }
645 
646 void
648 {
649  ArchiveHandle *AH = (ArchiveHandle *) AHX;
650 
651  ExecuteSqlCommand(AH, "BEGIN", "could not start database transaction");
652 }
653 
654 void
656 {
657  ArchiveHandle *AH = (ArchiveHandle *) AHX;
658 
659  ExecuteSqlCommand(AH, "COMMIT", "could not commit database transaction");
660 }
661 
662 void
664 {
665  /*
666  * If we are not restoring to a direct database connection, we have to
667  * guess about how to detect whether the blob exists. Assume new-style.
668  */
669  if (AH->connection == NULL ||
670  PQserverVersion(AH->connection) >= 90000)
671  {
672  ahprintf(AH,
673  "SELECT pg_catalog.lo_unlink(oid) "
674  "FROM pg_catalog.pg_largeobject_metadata "
675  "WHERE oid = '%u';\n",
676  oid);
677  }
678  else
679  {
680  /* Restoring to pre-9.0 server, so do it the old way */
681  ahprintf(AH,
682  "SELECT CASE WHEN EXISTS("
683  "SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u'"
684  ") THEN pg_catalog.lo_unlink('%u') END;\n",
685  oid, oid);
686  }
687 }
int PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
Definition: fe-exec.c:2221
static char password[100]
Definition: streamutil.c:41
PQExpBuffer curCmd
void EndDBCopyMode(Archive *AHX, const char *tocEntryTag)
Definition: pg_backup_db.c:618
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6011
sqlparseState state
int ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen)
Definition: pg_backup_db.c:563
PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
Definition: fe-connect.c:6187
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:5976
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
static void ExecuteSqlCommand(ArchiveHandle *AH, const char *qry, const char *desc)
Definition: pg_backup_db.c:446
void DisconnectDatabase(Archive *AHX)
Definition: pg_backup_db.c:343
static PGconn * _connectDB(ArchiveHandle *AH, const char *newdbname, const char *newUser)
Definition: pg_backup_db.c:128
void CommitTransaction(Archive *AHX)
Definition: pg_backup_db.c:655
#define gettext_noop(x)
Definition: c.h:139
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:536
void StartTransaction(Archive *AHX)
Definition: pg_backup_db.c:647
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3568
char * PQport(const PGconn *conn)
Definition: fe-connect.c:5932
int PQputCopyEnd(PGconn *conn, const char *errormsg)
Definition: fe-exec.c:2288
ExecStatusType
Definition: libpq-fe.h:82
PGcancel *volatile connCancel
unsigned int Oid
Definition: postgres_ext.h:31
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6001
const char * progname
Definition: pg_standby.c:37
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
PGconn * GetConnection(Archive *AHX)
Definition: pg_backup_db.c:372
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
int maxRemoteVersion
Definition: pg_backup.h:188
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:470
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:5887
void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...)
void ConnectDatabase(Archive *AHX, const char *dbname, const char *pghost, const char *pgport, const char *username, trivalue prompt_password)
Definition: pg_backup_db.c:246
bool isStandby
Definition: pg_backup.h:185
PGconn * conn
Definition: streamutil.c:42
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
void simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
Definition: sprompt.c:37
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:5895
static void notice_processor(void *arg, const char *message)
Definition: pg_backup_db.c:380
sqlparseInfo sqlparse
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PGresult * ExecuteSqlQueryForSingleRow(Archive *fout, char *query)
Definition: pg_backup_db.c:422
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:5966
char * pghost
Definition: pgbench.c:180
trivalue
Definition: vacuumlo.c:31
#define ngettext(s, p, n)
Definition: c.h:127
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
static const char * modulename
Definition: pg_backup_db.c:29
static char * username
Definition: initdb.c:131
static void ExecuteSimpleCommands(ArchiveHandle *AH, const char *buf, size_t bufLen)
Definition: pg_backup_db.c:498
static void die_on_query_failure(ArchiveHandle *AH, const char *modulename, const char *query)
Definition: pg_backup_db.c:387
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:5912
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define free(a)
Definition: header.h:65
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:5879
void write_msg(const char *modulename, const char *fmt,...)
#define NULL
Definition: c.h:229
void ExecuteSqlStatement(Archive *AHX, const char *query)
Definition: pg_backup_db.c:395
char * dbname
Definition: streamutil.c:38
ArchiverOutput outputKind
void exit_horribly(const char *modulename, const char *fmt,...)
static Datum values[MAXATTR]
Definition: bootstrap.c:162
static void _check_database_version(ArchiveHandle *AH)
Definition: pg_backup_db.c:36
int PQconnectionUsedPassword(const PGconn *conn)
Definition: fe-connect.c:6060
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
Definition: fe-connect.c:3844
char * remoteVersionStr
Definition: pg_backup.h:183
int PQconnectionNeedsPassword(const PGconn *conn)
Definition: fe-connect.c:6045
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
void set_archive_cancel_info(ArchiveHandle *AH, PGconn *conn)
Definition: parallel.c:742
int ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username)
Definition: pg_backup_db.c:86
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
void * arg
void DropBlobIfExists(ArchiveHandle *AH, Oid oid)
Definition: pg_backup_db.c:663
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:5958
char * pgport
Definition: pgbench.c:181
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
bool std_strings
Definition: pg_backup.h:196
PGresult * ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status)
Definition: pg_backup_db.c:407
int remoteVersion
Definition: pg_backup.h:184
static char * connstr
Definition: pg_dumpall.c:64