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