PostgreSQL Source Code  git master
common.h File Reference
#include "common/username.h"
#include "getopt_long.h"
#include "libpq-fe.h"
#include "pqexpbuffer.h"
Include dependency graph for common.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef void(* help_handler) (const char *progname)
 

Enumerations

enum  trivalue {
  TRI_DEFAULT, TRI_NO, TRI_YES, TRI_DEFAULT,
  TRI_NO, TRI_YES, TRI_DEFAULT, TRI_NO,
  TRI_YES, TRI_DEFAULT, TRI_NO, TRI_YES
}
 

Functions

void handle_help_version_opts (int argc, char *argv[], const char *fixed_progname, help_handler hlp)
 
PGconnconnectDatabase (const char *dbname, const char *pghost, const char *pgport, const char *pguser, enum trivalue prompt_password, const char *progname, bool echo, bool fail_ok, bool allow_password_reuse)
 
PGconnconnectMaintenanceDatabase (const char *maintenance_db, const char *pghost, const char *pgport, const char *pguser, enum trivalue prompt_password, const char *progname, bool echo)
 
void disconnectDatabase (PGconn *conn)
 
PGresultexecuteQuery (PGconn *conn, const char *query, bool echo)
 
void executeCommand (PGconn *conn, const char *query, bool echo)
 
bool executeMaintenanceCommand (PGconn *conn, const char *query, bool echo)
 
bool consumeQueryResult (PGconn *conn)
 
bool processQueryResult (PGconn *conn, PGresult *result)
 
void splitTableColumnsSpec (const char *spec, int encoding, char **table, const char **columns)
 
void appendQualifiedRelation (PQExpBuffer buf, const char *name, PGconn *conn, bool echo)
 
bool yesno_prompt (const char *question)
 

Typedef Documentation

◆ help_handler

typedef void(* help_handler) (const char *progname)

Definition at line 24 of file common.h.

Enumeration Type Documentation

◆ trivalue

enum trivalue
Enumerator
TRI_DEFAULT 
TRI_NO 
TRI_YES 
TRI_DEFAULT 
TRI_NO 
TRI_YES 
TRI_DEFAULT 
TRI_NO 
TRI_YES 
TRI_DEFAULT 
TRI_NO 
TRI_YES 

Definition at line 17 of file common.h.

18 {
20  TRI_NO,
21  TRI_YES
22 };
Definition: common.h:20
Definition: common.h:21

Function Documentation

◆ appendQualifiedRelation()

void appendQualifiedRelation ( PQExpBuffer  buf,
const char *  name,
PGconn conn,
bool  echo 
)

Definition at line 369 of file common.c.

References ALWAYS_SECURE_SEARCH_PATH_SQL, appendPQExpBufferStr(), appendStringLiteralConn(), PQExpBufferData::data, executeCommand(), executeQuery(), fmtQualifiedId(), initPQExpBuffer(), ngettext, pg_free(), pg_log_error, PQclear(), PQclientEncoding(), PQfinish(), PQgetvalue(), PQntuples(), splitTableColumnsSpec(), and termPQExpBuffer().

Referenced by cluster_one_database(), and run_reindex_command().

371 {
372  char *table;
373  const char *columns;
374  PQExpBufferData sql;
375  PGresult *res;
376  int ntups;
377 
378  splitTableColumnsSpec(spec, PQclientEncoding(conn), &table, &columns);
379 
380  /*
381  * Query must remain ABSOLUTELY devoid of unqualified names. This would
382  * be unnecessary given a regclassin() variant taking a search_path
383  * argument.
384  */
385  initPQExpBuffer(&sql);
387  "SELECT c.relname, ns.nspname\n"
388  " FROM pg_catalog.pg_class c,"
389  " pg_catalog.pg_namespace ns\n"
390  " WHERE c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n"
391  " AND c.oid OPERATOR(pg_catalog.=) ");
392  appendStringLiteralConn(&sql, table, conn);
393  appendPQExpBufferStr(&sql, "::pg_catalog.regclass;");
394 
395  executeCommand(conn, "RESET search_path;", echo);
396 
397  /*
398  * One row is a typical result, as is a nonexistent relation ERROR.
399  * regclassin() unconditionally accepts all-digits input as an OID; if no
400  * relation has that OID; this query returns no rows. Catalog corruption
401  * might elicit other row counts.
402  */
403  res = executeQuery(conn, sql.data, echo);
404  ntups = PQntuples(res);
405  if (ntups != 1)
406  {
407  pg_log_error(ngettext("query returned %d row instead of one: %s",
408  "query returned %d rows instead of one: %s",
409  ntups),
410  ntups, sql.data);
411  PQfinish(conn);
412  exit(1);
413  }
415  fmtQualifiedId(PQgetvalue(res, 0, 1),
416  PQgetvalue(res, 0, 0)));
417  appendPQExpBufferStr(buf, columns);
418  PQclear(res);
419  termPQExpBuffer(&sql);
420  pg_free(table);
421 
423 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
PGresult * executeQuery(PGconn *conn, const char *query, bool echo)
Definition: common.c:204
void executeCommand(PGconn *conn, const char *query, bool echo)
Definition: common.c:229
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
#define pg_log_error(...)
Definition: logging.h:80
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4170
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6732
#define ngettext(s, p, n)
Definition: c.h:1123
void PQclear(PGresult *res)
Definition: fe-exec.c:694
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:145
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:293
void splitTableColumnsSpec(const char *spec, int encoding, char **table, const char **columns)
Definition: common.c:334
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ connectDatabase()

PGconn* connectDatabase ( const char *  dbname,
const char *  pghost,
const char *  pgport,
const char *  pguser,
enum trivalue  prompt_password,
const char *  progname,
bool  echo,
bool  fail_ok,
bool  allow_password_reuse 
)

Definition at line 65 of file common.c.

References ALWAYS_SECURE_SEARCH_PATH_SQL, conn, CONNECTION_BAD, dbname, executeQuery(), free, password, pg_log_error, pghost, pgport, PQclear(), PQconnectdbParams(), PQconnectionNeedsPassword(), PQerrorMessage(), PQfinish(), PQstatus(), progname, simple_prompt(), TRI_NO, TRI_YES, and values.

Referenced by connectMaintenanceDatabase().

69 {
70  PGconn *conn;
71  bool new_pass;
72  static char *password = NULL;
73 
74  if (!allow_password_reuse && password)
75  {
76  free(password);
77  password = NULL;
78  }
79 
80  if (!password && prompt_password == TRI_YES)
81  password = simple_prompt("Password: ", false);
82 
83  /*
84  * Start the connection. Loop until we have a password if requested by
85  * backend.
86  */
87  do
88  {
89  const char *keywords[7];
90  const char *values[7];
91 
92  keywords[0] = "host";
93  values[0] = pghost;
94  keywords[1] = "port";
95  values[1] = pgport;
96  keywords[2] = "user";
97  values[2] = pguser;
98  keywords[3] = "password";
99  values[3] = password;
100  keywords[4] = "dbname";
101  values[4] = dbname;
102  keywords[5] = "fallback_application_name";
103  values[5] = progname;
104  keywords[6] = NULL;
105  values[6] = NULL;
106 
107  new_pass = false;
108  conn = PQconnectdbParams(keywords, values, true);
109 
110  if (!conn)
111  {
112  pg_log_error("could not connect to database %s: out of memory",
113  dbname);
114  exit(1);
115  }
116 
117  /*
118  * No luck? Trying asking (again) for a password.
119  */
120  if (PQstatus(conn) == CONNECTION_BAD &&
122  prompt_password != TRI_NO)
123  {
124  PQfinish(conn);
125  if (password)
126  free(password);
127  password = simple_prompt("Password: ", false);
128  new_pass = true;
129  }
130  } while (new_pass);
131 
132  /* check to see that the backend connection was successfully made */
133  if (PQstatus(conn) == CONNECTION_BAD)
134  {
135  if (fail_ok)
136  {
137  PQfinish(conn);
138  return NULL;
139  }
140  pg_log_error("could not connect to database %s: %s",
141  dbname, PQerrorMessage(conn));
142  exit(1);
143  }
144 
146 
147  return conn;
148 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
PGresult * executeQuery(PGconn *conn, const char *query, bool echo)
Definition: common.c:204
#define pg_log_error(...)
Definition: logging.h:80
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4170
char * simple_prompt(const char *prompt, bool echo)
Definition: sprompt.c:38
const char * progname
Definition: pg_standby.c:36
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:646
PGconn * conn
Definition: streamutil.c:54
static char * password
Definition: streamutil.c:53
char * pghost
Definition: pgbench.c:243
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
char * dbname
Definition: streamutil.c:51
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25
static Datum values[MAXATTR]
Definition: bootstrap.c:165
int PQconnectionNeedsPassword(const PGconn *conn)
Definition: fe-connect.c:6706
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6619
char * pgport
Definition: pgbench.c:244

◆ connectMaintenanceDatabase()

PGconn* connectMaintenanceDatabase ( const char *  maintenance_db,
const char *  pghost,
const char *  pgport,
const char *  pguser,
enum trivalue  prompt_password,
const char *  progname,
bool  echo 
)

Definition at line 154 of file common.c.

References conn, and connectDatabase().

Referenced by cluster_all_databases(), main(), reindex_all_databases(), and vacuum_all_databases().

158 {
159  PGconn *conn;
160 
161  /* If a maintenance database name was specified, just connect to it. */
162  if (maintenance_db)
163  return connectDatabase(maintenance_db, pghost, pgport, pguser,
164  prompt_password, progname, echo, false, false);
165 
166  /* Otherwise, try postgres first and then template1. */
167  conn = connectDatabase("postgres", pghost, pgport, pguser, prompt_password,
168  progname, echo, true, false);
169  if (!conn)
170  conn = connectDatabase("template1", pghost, pgport, pguser,
171  prompt_password, progname, echo, false, false);
172 
173  return conn;
174 }
const char * progname
Definition: pg_standby.c:36
PGconn * conn
Definition: streamutil.c:54
char * pghost
Definition: pgbench.c:243
PGconn * connectDatabase(const char *dbname, const char *pghost, const char *pgport, const char *pguser, enum trivalue prompt_password, const char *progname, bool echo, bool fail_ok, bool allow_password_reuse)
Definition: common.c:65
char * pgport
Definition: pgbench.c:244

◆ consumeQueryResult()

bool consumeQueryResult ( PGconn conn)

Definition at line 282 of file common.c.

References PQgetResult(), processQueryResult(), ResetCancelConn(), and SetCancelConn().

Referenced by ParallelSlotsWaitCompletion().

283 {
284  bool ok = true;
285  PGresult *result;
286 
287  SetCancelConn(conn);
288  while ((result = PQgetResult(conn)) != NULL)
289  {
290  if (!processQueryResult(conn, result))
291  ok = false;
292  }
293  ResetCancelConn();
294  return ok;
295 }
bool processQueryResult(PGconn *conn, PGresult *result)
Definition: common.c:303
void ResetCancelConn(void)
Definition: cancel.c:100
void SetCancelConn(PGconn *conn)
Definition: cancel.c:70
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1778

◆ disconnectDatabase()

void disconnectDatabase ( PGconn conn)

Definition at line 180 of file common.c.

References Assert, PQcancel(), PQfinish(), PQfreeCancel(), PQgetCancel(), PQTRANS_ACTIVE, and PQtransactionStatus().

Referenced by ParallelSlotsTerminate().

181 {
182  char errbuf[256];
183 
184  Assert(conn != NULL);
185 
186  if (PQtransactionStatus(conn) == PQTRANS_ACTIVE)
187  {
188  PGcancel *cancel;
189 
190  if ((cancel = PQgetCancel(conn)))
191  {
192  (void) PQcancel(cancel, errbuf, sizeof(errbuf));
193  PQfreeCancel(cancel);
194  }
195  }
196 
197  PQfinish(conn);
198 }
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:4314
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4170
PGcancel * PQgetCancel(PGconn *conn)
Definition: fe-connect.c:4291
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6627
#define Assert(condition)
Definition: c.h:745
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
Definition: fe-connect.c:4446

◆ executeCommand()

void executeCommand ( PGconn conn,
const char *  query,
bool  echo 
)

Definition at line 229 of file common.c.

References pg_log_error, pg_log_info, PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQfinish(), PQresultStatus(), and printf.

Referenced by appendQualifiedRelation().

230 {
231  PGresult *res;
232 
233  if (echo)
234  printf("%s\n", query);
235 
236  res = PQexec(conn, query);
237  if (!res ||
239  {
240  pg_log_error("query failed: %s", PQerrorMessage(conn));
241  pg_log_info("query was: %s", query);
242  PQfinish(conn);
243  exit(1);
244  }
245 
246  PQclear(res);
247 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
#define pg_log_error(...)
Definition: logging.h:80
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4170
#define printf(...)
Definition: port.h:199
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void PQclear(PGresult *res)
Definition: fe-exec.c:694
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define pg_log_info(...)
Definition: logging.h:88

◆ executeMaintenanceCommand()

bool executeMaintenanceCommand ( PGconn conn,
const char *  query,
bool  echo 
)

Definition at line 256 of file common.c.

References PGRES_COMMAND_OK, PQclear(), PQexec(), PQresultStatus(), printf, ResetCancelConn(), and SetCancelConn().

Referenced by cluster_one_database(), and run_reindex_command().

257 {
258  PGresult *res;
259  bool r;
260 
261  if (echo)
262  printf("%s\n", query);
263 
264  SetCancelConn(conn);
265  res = PQexec(conn, query);
266  ResetCancelConn();
267 
268  r = (res && PQresultStatus(res) == PGRES_COMMAND_OK);
269 
270  if (res)
271  PQclear(res);
272 
273  return r;
274 }
void ResetCancelConn(void)
Definition: cancel.c:100
#define printf(...)
Definition: port.h:199
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void SetCancelConn(PGconn *conn)
Definition: cancel.c:70
void PQclear(PGresult *res)
Definition: fe-exec.c:694
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ executeQuery()

PGresult* executeQuery ( PGconn conn,
const char *  query,
bool  echo 
)

Definition at line 204 of file common.c.

References pg_log_error, pg_log_info, PGRES_TUPLES_OK, PQerrorMessage(), PQexec(), PQfinish(), PQresultStatus(), and printf.

Referenced by appendQualifiedRelation(), and connectDatabase().

205 {
206  PGresult *res;
207 
208  if (echo)
209  printf("%s\n", query);
210 
211  res = PQexec(conn, query);
212  if (!res ||
214  {
215  pg_log_error("query failed: %s", PQerrorMessage(conn));
216  pg_log_info("query was: %s", query);
217  PQfinish(conn);
218  exit(1);
219  }
220 
221  return res;
222 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
#define pg_log_error(...)
Definition: logging.h:80
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4170
#define printf(...)
Definition: port.h:199
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define pg_log_info(...)
Definition: logging.h:88

◆ handle_help_version_opts()

void handle_help_version_opts ( int  argc,
char *  argv[],
const char *  fixed_progname,
help_handler  hlp 
)

Definition at line 34 of file common.c.

References get_progname(), and printf.

Referenced by main().

36 {
37  if (argc > 1)
38  {
39  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
40  {
41  hlp(get_progname(argv[0]));
42  exit(0);
43  }
44  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
45  {
46  printf("%s (PostgreSQL) " PG_VERSION "\n", fixed_progname);
47  exit(0);
48  }
49  }
50 }
const char * get_progname(const char *argv0)
Definition: path.c:453
#define printf(...)
Definition: port.h:199

◆ processQueryResult()

bool processQueryResult ( PGconn conn,
PGresult result 
)

Definition at line 303 of file common.c.

References ERRCODE_UNDEFINED_TABLE, PG_DIAG_SQLSTATE, pg_log_error, PGRES_COMMAND_OK, PQclear(), PQdb(), PQerrorMessage(), PQresultErrorField(), and PQresultStatus().

Referenced by consumeQueryResult(), and ParallelSlotsGetIdle().

304 {
305  /*
306  * If it's an error, report it. Errors about a missing table are harmless
307  * so we continue processing; but die for other errors.
308  */
309  if (PQresultStatus(result) != PGRES_COMMAND_OK)
310  {
311  char *sqlState = PQresultErrorField(result, PG_DIAG_SQLSTATE);
312 
313  pg_log_error("processing of database \"%s\" failed: %s",
314  PQdb(conn), PQerrorMessage(conn));
315 
316  if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) != 0)
317  {
318  PQclear(result);
319  return false;
320  }
321  }
322 
323  PQclear(result);
324  return true;
325 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
#define pg_log_error(...)
Definition: logging.h:80
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
#define ERRCODE_UNDEFINED_TABLE
Definition: common.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:694
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6522
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2754

◆ splitTableColumnsSpec()

void splitTableColumnsSpec ( const char *  spec,
int  encoding,
char **  table,
const char **  columns 
)

Definition at line 334 of file common.c.

References pnstrdup(), and PQmblen().

Referenced by appendQualifiedRelation(), and vacuum_one_database().

336 {
337  bool inquotes = false;
338  const char *cp = spec;
339 
340  /*
341  * Find the first '(' not identifier-quoted. Based on
342  * dequote_downcase_identifier().
343  */
344  while (*cp && (*cp != '(' || inquotes))
345  {
346  if (*cp == '"')
347  {
348  if (inquotes && cp[1] == '"')
349  cp++; /* pair does not affect quoting */
350  else
351  inquotes = !inquotes;
352  cp++;
353  }
354  else
355  cp += PQmblen(cp, encoding);
356  }
357  *table = pnstrdup(spec, cp - spec);
358  *columns = cp;
359 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1198
int32 encoding
Definition: pg_database.h:41
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1221

◆ yesno_prompt()

bool yesno_prompt ( const char *  question)

Definition at line 436 of file common.c.

References _, free, PG_NOLETTER, PG_YESLETTER, printf, simple_prompt(), and snprintf.

Referenced by main().

437 {
438  char prompt[256];
439 
440  /*------
441  translator: This is a question followed by the translated options for
442  "yes" and "no". */
443  snprintf(prompt, sizeof(prompt), _("%s (%s/%s) "),
444  _(question), _(PG_YESLETTER), _(PG_NOLETTER));
445 
446  for (;;)
447  {
448  char *resp;
449 
450  resp = simple_prompt(prompt, true);
451 
452  if (strcmp(resp, _(PG_YESLETTER)) == 0)
453  {
454  free(resp);
455  return true;
456  }
457  if (strcmp(resp, _(PG_NOLETTER)) == 0)
458  {
459  free(resp);
460  return false;
461  }
462  free(resp);
463 
464  printf(_("Please answer \"%s\" or \"%s\".\n"),
466  }
467 }
#define PG_YESLETTER
Definition: common.c:431
#define printf(...)
Definition: port.h:199
char * simple_prompt(const char *prompt, bool echo)
Definition: sprompt.c:38
#define PG_NOLETTER
Definition: common.c:433
#define free(a)
Definition: header.h:65
#define snprintf
Definition: port.h:193
#define _(x)
Definition: elog.c:88