PostgreSQL Source Code  git master
common.c File Reference
#include "postgres_fe.h"
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <signal.h>
#include <unistd.h>
#include "command.h"
#include "common.h"
#include "common/logging.h"
#include "copy.h"
#include "crosstabview.h"
#include "fe_utils/cancel.h"
#include "fe_utils/mbprint.h"
#include "fe_utils/string_utils.h"
#include "portability/instr_time.h"
#include "settings.h"
Include dependency graph for common.c:

Go to the source code of this file.

Functions

static bool DescribeQuery (const char *query, double *elapsed_msec)
 
static bool ExecQueryUsingCursor (const char *query, double *elapsed_msec)
 
static bool command_no_begin (const char *query)
 
static bool is_select_command (const char *query)
 
bool openQueryOutputFile (const char *fname, FILE **fout, bool *is_pipe)
 
bool setQFout (const char *fname)
 
char * psql_get_variable (const char *varname, PsqlScanQuoteType quote, void *passthrough)
 
void NoticeProcessor (void *arg, const char *message)
 
static void psql_cancel_callback (void)
 
void psql_setup_cancel_handler (void)
 
static bool ConnectionUp (void)
 
static bool CheckConnection (void)
 
static bool AcceptResult (const PGresult *result)
 
static void SetResultVariables (PGresult *results, bool success)
 
static void ClearOrSaveResult (PGresult *result)
 
static void PrintTiming (double elapsed_msec)
 
PGresultPSQLexec (const char *query)
 
int PSQLexecWatch (const char *query, const printQueryOpt *opt)
 
static void PrintNotifications (void)
 
static bool PrintQueryTuples (const PGresult *results)
 
static bool StoreQueryTuple (const PGresult *result)
 
static bool ExecQueryTuples (const PGresult *result)
 
static bool ProcessResult (PGresult **results)
 
static void PrintQueryStatus (PGresult *results)
 
static bool PrintQueryResults (PGresult *results)
 
bool SendQuery (const char *query)
 
static const char * skip_white_space (const char *query)
 
bool is_superuser (void)
 
bool standard_strings (void)
 
const char * session_username (void)
 
void expand_tilde (char **filename)
 
static int uri_prefix_length (const char *connstr)
 
bool recognized_connection_string (const char *connstr)
 

Variables

volatile bool sigint_interrupt_enabled = false
 
sigjmp_buf sigint_interrupt_jmp
 

Function Documentation

◆ AcceptResult()

static bool AcceptResult ( const PGresult result)
static

Definition at line 352 of file common.c.

References CheckConnection(), _psqlSettings::db, error(), pg_log_error, pg_log_info, PGRES_BAD_RESPONSE, PGRES_COMMAND_OK, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_NONFATAL_ERROR, PGRES_TUPLES_OK, PQerrorMessage(), PQresultStatus(), and pset.

Referenced by DescribeQuery(), ExecQueryUsingCursor(), ProcessResult(), PSQLexec(), and PSQLexecWatch().

353 {
354  bool OK;
355 
356  if (!result)
357  OK = false;
358  else
359  switch (PQresultStatus(result))
360  {
361  case PGRES_COMMAND_OK:
362  case PGRES_TUPLES_OK:
363  case PGRES_EMPTY_QUERY:
364  case PGRES_COPY_IN:
365  case PGRES_COPY_OUT:
366  /* Fine, do nothing */
367  OK = true;
368  break;
369 
370  case PGRES_BAD_RESPONSE:
372  case PGRES_FATAL_ERROR:
373  OK = false;
374  break;
375 
376  default:
377  OK = false;
378  pg_log_error("unexpected PQresultStatus: %d",
379  PQresultStatus(result));
380  break;
381  }
382 
383  if (!OK)
384  {
385  const char *error = PQerrorMessage(pset.db);
386 
387  if (strlen(error))
388  pg_log_info("%s", error);
389 
390  CheckConnection();
391  }
392 
393  return OK;
394 }
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
PsqlSettings pset
Definition: startup.c:31
static void error(void)
Definition: sql-dyntest.c:147
#define pg_log_error(...)
Definition: logging.h:79
static bool CheckConnection(void)
Definition: common.c:295
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
#define pg_log_info(...)
Definition: logging.h:87

◆ CheckConnection()

static bool CheckConnection ( void  )
static

Definition at line 295 of file common.c.

References _, connection_warnings(), ConnectionUp(), _psqlSettings::cur_cmd_interactive, _psqlSettings::db, EXIT_BADCONN, fprintf, pg_log_fatal, PQfinish(), PQreset(), pset, ResetCancelConn(), SyncVariables(), and UnsyncVariables().

Referenced by AcceptResult(), and ProcessResult().

296 {
297  bool OK;
298 
299  OK = ConnectionUp();
300  if (!OK)
301  {
303  {
304  pg_log_fatal("connection to server was lost");
305  exit(EXIT_BADCONN);
306  }
307 
308  fprintf(stderr, _("The connection to the server was lost. Attempting reset: "));
309  PQreset(pset.db);
310  OK = ConnectionUp();
311  if (!OK)
312  {
313  fprintf(stderr, _("Failed.\n"));
314 
315  /*
316  * Transition to having no connection. Keep this bit in sync with
317  * do_connect().
318  */
319  PQfinish(pset.db);
320  pset.db = NULL;
321  ResetCancelConn();
322  UnsyncVariables();
323  }
324  else
325  {
326  fprintf(stderr, _("Succeeded.\n"));
327 
328  /*
329  * Re-sync, just in case anything changed. Keep this in sync with
330  * do_connect().
331  */
332  SyncVariables();
333  connection_warnings(false); /* Must be after SyncVariables */
334  }
335  }
336 
337  return OK;
338 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
void SyncVariables(void)
Definition: command.c:3461
void ResetCancelConn(void)
Definition: cancel.c:100
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4170
static bool ConnectionUp(void)
Definition: common.c:277
#define fprintf
Definition: port.h:197
void UnsyncVariables(void)
Definition: command.c:3502
#define EXIT_BADCONN
Definition: settings.h:157
bool cur_cmd_interactive
Definition: settings.h:107
void connection_warnings(bool in_startup)
Definition: command.c:3338
#define _(x)
Definition: elog.c:88
void PQreset(PGconn *conn)
Definition: fe-connect.c:4184
#define pg_log_fatal(...)
Definition: logging.h:75

◆ ClearOrSaveResult()

static void ClearOrSaveResult ( PGresult result)
static

Definition at line 451 of file common.c.

References _psqlSettings::last_error_result, PGRES_FATAL_ERROR, PGRES_NONFATAL_ERROR, PQclear(), PQresultStatus(), and pset.

Referenced by DescribeQuery(), ExecQueryUsingCursor(), PSQLexec(), PSQLexecWatch(), and SendQuery().

452 {
453  if (result)
454  {
455  switch (PQresultStatus(result))
456  {
458  case PGRES_FATAL_ERROR:
461  pset.last_error_result = result;
462  break;
463 
464  default:
465  PQclear(result);
466  break;
467  }
468  }
469 }
PsqlSettings pset
Definition: startup.c:31
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
PGresult * last_error_result
Definition: settings.h:89
void PQclear(PGresult *res)
Definition: fe-exec.c:694

◆ command_no_begin()

static bool command_no_begin ( const char *  query)
static

Definition at line 1895 of file common.c.

References _psqlSettings::encoding, pg_strncasecmp(), PQmblen(), pset, and skip_white_space().

Referenced by SendQuery().

1896 {
1897  int wordlen;
1898 
1899  /*
1900  * First we must advance over any whitespace and comments.
1901  */
1902  query = skip_white_space(query);
1903 
1904  /*
1905  * Check word length (since "beginx" is not "begin").
1906  */
1907  wordlen = 0;
1908  while (isalpha((unsigned char) query[wordlen]))
1909  wordlen += PQmblen(&query[wordlen], pset.encoding);
1910 
1911  /*
1912  * Transaction control commands. These should include every keyword that
1913  * gives rise to a TransactionStmt in the backend grammar, except for the
1914  * savepoint-related commands.
1915  *
1916  * (We assume that START must be START TRANSACTION, since there is
1917  * presently no other "START foo" command.)
1918  */
1919  if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
1920  return true;
1921  if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
1922  return true;
1923  if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
1924  return true;
1925  if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
1926  return true;
1927  if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
1928  return true;
1929  if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
1930  return true;
1931  if (wordlen == 7 && pg_strncasecmp(query, "prepare", 7) == 0)
1932  {
1933  /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
1934  query += wordlen;
1935 
1936  query = skip_white_space(query);
1937 
1938  wordlen = 0;
1939  while (isalpha((unsigned char) query[wordlen]))
1940  wordlen += PQmblen(&query[wordlen], pset.encoding);
1941 
1942  if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0)
1943  return true;
1944  return false;
1945  }
1946 
1947  /*
1948  * Commands not allowed within transactions. The statements checked for
1949  * here should be exactly those that call PreventInTransactionBlock() in
1950  * the backend.
1951  */
1952  if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
1953  return true;
1954  if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
1955  {
1956  /* CLUSTER with any arguments is allowed in transactions */
1957  query += wordlen;
1958 
1959  query = skip_white_space(query);
1960 
1961  if (isalpha((unsigned char) query[0]))
1962  return false; /* has additional words */
1963  return true; /* it's CLUSTER without arguments */
1964  }
1965 
1966  if (wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0)
1967  {
1968  query += wordlen;
1969 
1970  query = skip_white_space(query);
1971 
1972  wordlen = 0;
1973  while (isalpha((unsigned char) query[wordlen]))
1974  wordlen += PQmblen(&query[wordlen], pset.encoding);
1975 
1976  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
1977  return true;
1978  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
1979  return true;
1980 
1981  /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
1982  if (wordlen == 6 && pg_strncasecmp(query, "unique", 6) == 0)
1983  {
1984  query += wordlen;
1985 
1986  query = skip_white_space(query);
1987 
1988  wordlen = 0;
1989  while (isalpha((unsigned char) query[wordlen]))
1990  wordlen += PQmblen(&query[wordlen], pset.encoding);
1991  }
1992 
1993  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
1994  {
1995  query += wordlen;
1996 
1997  query = skip_white_space(query);
1998 
1999  wordlen = 0;
2000  while (isalpha((unsigned char) query[wordlen]))
2001  wordlen += PQmblen(&query[wordlen], pset.encoding);
2002 
2003  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2004  return true;
2005  }
2006 
2007  return false;
2008  }
2009 
2010  if (wordlen == 5 && pg_strncasecmp(query, "alter", 5) == 0)
2011  {
2012  query += wordlen;
2013 
2014  query = skip_white_space(query);
2015 
2016  wordlen = 0;
2017  while (isalpha((unsigned char) query[wordlen]))
2018  wordlen += PQmblen(&query[wordlen], pset.encoding);
2019 
2020  /* ALTER SYSTEM isn't allowed in xacts */
2021  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2022  return true;
2023 
2024  return false;
2025  }
2026 
2027  /*
2028  * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
2029  * aren't really valid commands so we don't care much. The other four
2030  * possible matches are correct.
2031  */
2032  if ((wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
2033  (wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
2034  {
2035  query += wordlen;
2036 
2037  query = skip_white_space(query);
2038 
2039  wordlen = 0;
2040  while (isalpha((unsigned char) query[wordlen]))
2041  wordlen += PQmblen(&query[wordlen], pset.encoding);
2042 
2043  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
2044  return true;
2045  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2046  return true;
2047  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
2048  return true;
2049  if (wordlen == 5 && (pg_strncasecmp(query, "index", 5) == 0 ||
2050  pg_strncasecmp(query, "table", 5) == 0))
2051  {
2052  query += wordlen;
2053  query = skip_white_space(query);
2054  wordlen = 0;
2055  while (isalpha((unsigned char) query[wordlen]))
2056  wordlen += PQmblen(&query[wordlen], pset.encoding);
2057 
2058  /*
2059  * REINDEX [ TABLE | INDEX ] CONCURRENTLY are not allowed in
2060  * xacts.
2061  */
2062  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2063  return true;
2064  }
2065 
2066  /* DROP INDEX CONCURRENTLY isn't allowed in xacts */
2067  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
2068  {
2069  query += wordlen;
2070 
2071  query = skip_white_space(query);
2072 
2073  wordlen = 0;
2074  while (isalpha((unsigned char) query[wordlen]))
2075  wordlen += PQmblen(&query[wordlen], pset.encoding);
2076 
2077  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2078  return true;
2079 
2080  return false;
2081  }
2082 
2083  return false;
2084  }
2085 
2086  /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */
2087  if (wordlen == 7 && pg_strncasecmp(query, "discard", 7) == 0)
2088  {
2089  query += wordlen;
2090 
2091  query = skip_white_space(query);
2092 
2093  wordlen = 0;
2094  while (isalpha((unsigned char) query[wordlen]))
2095  wordlen += PQmblen(&query[wordlen], pset.encoding);
2096 
2097  if (wordlen == 3 && pg_strncasecmp(query, "all", 3) == 0)
2098  return true;
2099  return false;
2100  }
2101 
2102  return false;
2103 }
PsqlSettings pset
Definition: startup.c:31
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
int encoding
Definition: settings.h:83
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1221
static const char * skip_white_space(const char *query)
Definition: common.c:1831

◆ ConnectionUp()

static bool ConnectionUp ( void  )
static

Definition at line 277 of file common.c.

References CONNECTION_BAD, _psqlSettings::db, PQstatus(), and pset.

Referenced by CheckConnection(), and SendQuery().

278 {
279  return PQstatus(pset.db) != CONNECTION_BAD;
280 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6619

◆ DescribeQuery()

static bool DescribeQuery ( const char *  query,
double *  elapsed_msec 
)
static

Definition at line 1457 of file common.c.

References _, AcceptResult(), appendPQExpBuffer(), appendPQExpBufferStr(), before(), buf, ClearOrSaveResult(), PQExpBufferData::data, _psqlSettings::db, fprintf, gettext_noop, i, initPQExpBuffer(), INSTR_TIME_GET_MILLISEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SUBTRACT, name, pg_log_info, PGRES_COMMAND_OK, PQclear(), PQdescribePrepared(), PQerrorMessage(), PQescapeLiteral(), PQexec(), PQfmod(), PQfname(), PQfreemem(), PQftype(), PQnfields(), PQprepare(), PQresultStatus(), printfPQExpBuffer(), PrintQueryResults(), pset, _psqlSettings::queryFout, SetResultVariables(), termPQExpBuffer(), and _psqlSettings::timing.

Referenced by SendQuery().

1458 {
1459  PGresult *results;
1460  bool OK;
1462  after;
1463 
1464  *elapsed_msec = 0;
1465 
1466  if (pset.timing)
1467  INSTR_TIME_SET_CURRENT(before);
1468 
1469  /*
1470  * To parse the query but not execute it, we prepare it, using the unnamed
1471  * prepared statement. This is invisible to psql users, since there's no
1472  * way to access the unnamed prepared statement from psql user space. The
1473  * next Parse or Query protocol message would overwrite the statement
1474  * anyway. (So there's no great need to clear it when done, which is a
1475  * good thing because libpq provides no easy way to do that.)
1476  */
1477  results = PQprepare(pset.db, "", query, 0, NULL);
1478  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1479  {
1481  SetResultVariables(results, false);
1482  ClearOrSaveResult(results);
1483  return false;
1484  }
1485  PQclear(results);
1486 
1487  results = PQdescribePrepared(pset.db, "");
1488  OK = AcceptResult(results) &&
1489  (PQresultStatus(results) == PGRES_COMMAND_OK);
1490  if (OK && results)
1491  {
1492  if (PQnfields(results) > 0)
1493  {
1495  int i;
1496 
1497  initPQExpBuffer(&buf);
1498 
1499  printfPQExpBuffer(&buf,
1500  "SELECT name AS \"%s\", pg_catalog.format_type(tp, tpm) AS \"%s\"\n"
1501  "FROM (VALUES ",
1502  gettext_noop("Column"),
1503  gettext_noop("Type"));
1504 
1505  for (i = 0; i < PQnfields(results); i++)
1506  {
1507  const char *name;
1508  char *escname;
1509 
1510  if (i > 0)
1511  appendPQExpBufferStr(&buf, ",");
1512 
1513  name = PQfname(results, i);
1514  escname = PQescapeLiteral(pset.db, name, strlen(name));
1515 
1516  if (escname == NULL)
1517  {
1519  PQclear(results);
1520  termPQExpBuffer(&buf);
1521  return false;
1522  }
1523 
1524  appendPQExpBuffer(&buf, "(%s, '%u'::pg_catalog.oid, %d)",
1525  escname,
1526  PQftype(results, i),
1527  PQfmod(results, i));
1528 
1529  PQfreemem(escname);
1530  }
1531 
1532  appendPQExpBufferStr(&buf, ") s(name, tp, tpm)");
1533  PQclear(results);
1534 
1535  results = PQexec(pset.db, buf.data);
1536  OK = AcceptResult(results);
1537 
1538  if (pset.timing)
1539  {
1540  INSTR_TIME_SET_CURRENT(after);
1541  INSTR_TIME_SUBTRACT(after, before);
1542  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1543  }
1544 
1545  if (OK && results)
1546  OK = PrintQueryResults(results);
1547 
1548  termPQExpBuffer(&buf);
1549  }
1550  else
1552  _("The command has no result, or the result has no columns.\n"));
1553  }
1554 
1555  SetResultVariables(results, OK);
1556  ClearOrSaveResult(results);
1557 
1558  return OK;
1559 }
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1104
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2777
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
Definition: fe-exec.c:1983
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
Definition: fe-exec.c:2156
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:451
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2855
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
static void SetResultVariables(PGresult *results, bool success)
Definition: common.c:409
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:202
struct timeval instr_time
Definition: instr_time.h:150
#define gettext_noop(x)
Definition: c.h:1137
FILE * queryFout
Definition: settings.h:84
#define fprintf
Definition: port.h:197
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
static bool AcceptResult(const PGresult *result)
Definition: common.c:352
static int before(chr x, chr y)
Definition: regc_locale.c:496
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3007
static char * buf
Definition: pg_test_fsync.c:67
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3564
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int PQfmod(const PGresult *res, int field_num)
Definition: fe-exec.c:3029
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
const char * name
Definition: encode.c:561
int i
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define _(x)
Definition: elog.c:88
void PQfreemem(void *ptr)
Definition: fe-exec.c:3296
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
#define pg_log_info(...)
Definition: logging.h:87

◆ ExecQueryTuples()

static bool ExecQueryTuples ( const PGresult result)
static

Definition at line 815 of file common.c.

References cancel_pressed, _psqlSettings::echo, _psqlSettings::gexec_flag, _psqlSettings::on_error_stop, PQgetisnull(), PQgetvalue(), PQnfields(), PQntuples(), pset, PSQL_ECHO_ALL, SendQuery(), _psqlSettings::singlestep, generate_unaccent_rules::stdout, and success.

Referenced by PrintQueryResults().

816 {
817  bool success = true;
818  int nrows = PQntuples(result);
819  int ncolumns = PQnfields(result);
820  int r,
821  c;
822 
823  /*
824  * We must turn off gexec_flag to avoid infinite recursion. Note that
825  * this allows ExecQueryUsingCursor to be applied to the individual query
826  * results. SendQuery prevents it from being applied when fetching the
827  * queries-to-execute, because it can't handle recursion either.
828  */
829  pset.gexec_flag = false;
830 
831  for (r = 0; r < nrows; r++)
832  {
833  for (c = 0; c < ncolumns; c++)
834  {
835  if (!PQgetisnull(result, r, c))
836  {
837  const char *query = PQgetvalue(result, r, c);
838 
839  /* Abandon execution if cancel_pressed */
840  if (cancel_pressed)
841  goto loop_exit;
842 
843  /*
844  * ECHO_ALL mode should echo these queries, but SendQuery
845  * assumes that MainLoop did that, so we have to do it here.
846  */
848  {
849  puts(query);
850  fflush(stdout);
851  }
852 
853  if (!SendQuery(query))
854  {
855  /* Error - abandon execution if ON_ERROR_STOP */
856  success = false;
857  if (pset.on_error_stop)
858  goto loop_exit;
859  }
860  }
861  }
862  }
863 
864 loop_exit:
865 
866  /*
867  * Restore state. We know gexec_flag was on, else we'd not be here. (We
868  * also know it'll get turned off at end of command, but that's not ours
869  * to do here.)
870  */
871  pset.gexec_flag = true;
872 
873  /* Return true if all queries were successful */
874  return success;
875 }
PSQL_ECHO echo
Definition: settings.h:134
bool singlestep
Definition: settings.h:129
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2777
PsqlSettings pset
Definition: startup.c:31
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
bool gexec_flag
Definition: settings.h:98
bool on_error_stop
Definition: settings.h:126
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
char * c
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
bool SendQuery(const char *query)
Definition: common.c:1179
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3188
static bool success
Definition: initdb.c:161

◆ ExecQueryUsingCursor()

static bool ExecQueryUsingCursor ( const char *  query,
double *  elapsed_msec 
)
static

Definition at line 1573 of file common.c.

References AcceptResult(), appendPQExpBuffer(), Assert, before(), buf, cancel_pressed, cleanup(), ClearOrSaveResult(), ClosePager(), PQExpBufferData::data, _psqlSettings::db, disable_sigpipe_trap(), _psqlSettings::fetch_count, _psqlSettings::gfname, _psqlSettings::gset_prefix, initPQExpBuffer(), INSTR_TIME_GET_MILLISEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SUBTRACT, INT64_FORMAT, _psqlSettings::logfile, openQueryOutputFile(), PageOutput(), PGRES_COMMAND_OK, PGRES_TUPLES_OK, _psqlSettings::popt, PQclear(), PQexec(), PQntuples(), PQresultStatus(), PQTRANS_IDLE, PQtransactionStatus(), printQuery(), printTableOpt::prior_records, pset, _psqlSettings::queryFout, restore_sigpipe_trap(), SetResultVariables(), SetVariable(), snprintf, printTableOpt::start_table, generate_unaccent_rules::stdout, printTableOpt::stop_table, StoreQueryTuple(), termPQExpBuffer(), _psqlSettings::timing, printQueryOpt::topt, and _psqlSettings::vars.

Referenced by SendQuery().

1574 {
1575  bool OK = true;
1576  PGresult *results;
1578  printQueryOpt my_popt = pset.popt;
1579  FILE *fout;
1580  bool is_pipe;
1581  bool is_pager = false;
1582  bool started_txn = false;
1583  int64 total_tuples = 0;
1584  int ntuples;
1585  int fetch_count;
1586  char fetch_cmd[64];
1588  after;
1589  int flush_error;
1590 
1591  *elapsed_msec = 0;
1592 
1593  /* initialize print options for partial table output */
1594  my_popt.topt.start_table = true;
1595  my_popt.topt.stop_table = false;
1596  my_popt.topt.prior_records = 0;
1597 
1598  if (pset.timing)
1599  INSTR_TIME_SET_CURRENT(before);
1600 
1601  /* if we're not in a transaction, start one */
1603  {
1604  results = PQexec(pset.db, "BEGIN");
1605  OK = AcceptResult(results) &&
1606  (PQresultStatus(results) == PGRES_COMMAND_OK);
1607  ClearOrSaveResult(results);
1608  if (!OK)
1609  return false;
1610  started_txn = true;
1611  }
1612 
1613  /* Send DECLARE CURSOR */
1614  initPQExpBuffer(&buf);
1615  appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1616  query);
1617 
1618  results = PQexec(pset.db, buf.data);
1619  OK = AcceptResult(results) &&
1620  (PQresultStatus(results) == PGRES_COMMAND_OK);
1621  if (!OK)
1622  SetResultVariables(results, OK);
1623  ClearOrSaveResult(results);
1624  termPQExpBuffer(&buf);
1625  if (!OK)
1626  goto cleanup;
1627 
1628  if (pset.timing)
1629  {
1630  INSTR_TIME_SET_CURRENT(after);
1631  INSTR_TIME_SUBTRACT(after, before);
1632  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1633  }
1634 
1635  /*
1636  * In \gset mode, we force the fetch count to be 2, so that we will throw
1637  * the appropriate error if the query returns more than one row.
1638  */
1639  if (pset.gset_prefix)
1640  fetch_count = 2;
1641  else
1642  fetch_count = pset.fetch_count;
1643 
1644  snprintf(fetch_cmd, sizeof(fetch_cmd),
1645  "FETCH FORWARD %d FROM _psql_cursor",
1646  fetch_count);
1647 
1648  /* prepare to write output to \g argument, if any */
1649  if (pset.gfname)
1650  {
1651  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
1652  {
1653  OK = false;
1654  goto cleanup;
1655  }
1656  if (is_pipe)
1658  }
1659  else
1660  {
1661  fout = pset.queryFout;
1662  is_pipe = false; /* doesn't matter */
1663  }
1664 
1665  /* clear any pre-existing error indication on the output stream */
1666  clearerr(fout);
1667 
1668  for (;;)
1669  {
1670  if (pset.timing)
1671  INSTR_TIME_SET_CURRENT(before);
1672 
1673  /* get fetch_count tuples at a time */
1674  results = PQexec(pset.db, fetch_cmd);
1675 
1676  if (pset.timing)
1677  {
1678  INSTR_TIME_SET_CURRENT(after);
1679  INSTR_TIME_SUBTRACT(after, before);
1680  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1681  }
1682 
1683  if (PQresultStatus(results) != PGRES_TUPLES_OK)
1684  {
1685  /* shut down pager before printing error message */
1686  if (is_pager)
1687  {
1688  ClosePager(fout);
1689  is_pager = false;
1690  }
1691 
1692  OK = AcceptResult(results);
1693  Assert(!OK);
1694  SetResultVariables(results, OK);
1695  ClearOrSaveResult(results);
1696  break;
1697  }
1698 
1699  if (pset.gset_prefix)
1700  {
1701  /* StoreQueryTuple will complain if not exactly one row */
1702  OK = StoreQueryTuple(results);
1703  ClearOrSaveResult(results);
1704  break;
1705  }
1706 
1707  /*
1708  * Note we do not deal with \gdesc, \gexec or \crosstabview modes here
1709  */
1710 
1711  ntuples = PQntuples(results);
1712  total_tuples += ntuples;
1713 
1714  if (ntuples < fetch_count)
1715  {
1716  /* this is the last result set, so allow footer decoration */
1717  my_popt.topt.stop_table = true;
1718  }
1719  else if (fout == stdout && !is_pager)
1720  {
1721  /*
1722  * If query requires multiple result sets, hack to ensure that
1723  * only one pager instance is used for the whole mess
1724  */
1725  fout = PageOutput(INT_MAX, &(my_popt.topt));
1726  is_pager = true;
1727  }
1728 
1729  printQuery(results, &my_popt, fout, is_pager, pset.logfile);
1730 
1731  ClearOrSaveResult(results);
1732 
1733  /* after the first result set, disallow header decoration */
1734  my_popt.topt.start_table = false;
1735  my_popt.topt.prior_records += ntuples;
1736 
1737  /*
1738  * Make sure to flush the output stream, so intermediate results are
1739  * visible to the client immediately. We check the results because if
1740  * the pager dies/exits/etc, there's no sense throwing more data at
1741  * it.
1742  */
1743  flush_error = fflush(fout);
1744 
1745  /*
1746  * Check if we are at the end, if a cancel was pressed, or if there
1747  * were any errors either trying to flush out the results, or more
1748  * generally on the output stream at all. If we hit any errors
1749  * writing things to the stream, we presume $PAGER has disappeared and
1750  * stop bothering to pull down more data.
1751  */
1752  if (ntuples < fetch_count || cancel_pressed || flush_error ||
1753  ferror(fout))
1754  break;
1755  }
1756 
1757  if (pset.gfname)
1758  {
1759  /* close \g argument file/pipe */
1760  if (is_pipe)
1761  {
1762  pclose(fout);
1764  }
1765  else
1766  fclose(fout);
1767  }
1768  else if (is_pager)
1769  {
1770  /* close transient pager */
1771  ClosePager(fout);
1772  }
1773 
1774  if (OK)
1775  {
1776  /*
1777  * We don't have a PGresult here, and even if we did it wouldn't have
1778  * the right row count, so fake SetResultVariables(). In error cases,
1779  * we already set the result variables above.
1780  */
1781  char buf[32];
1782 
1783  SetVariable(pset.vars, "ERROR", "false");
1784  SetVariable(pset.vars, "SQLSTATE", "00000");
1785  snprintf(buf, sizeof(buf), INT64_FORMAT, total_tuples);
1786  SetVariable(pset.vars, "ROW_COUNT", buf);
1787  }
1788 
1789 cleanup:
1790  if (pset.timing)
1791  INSTR_TIME_SET_CURRENT(before);
1792 
1793  /*
1794  * We try to close the cursor on either success or failure, but on failure
1795  * ignore the result (it's probably just a bleat about being in an aborted
1796  * transaction)
1797  */
1798  results = PQexec(pset.db, "CLOSE _psql_cursor");
1799  if (OK)
1800  {
1801  OK = AcceptResult(results) &&
1802  (PQresultStatus(results) == PGRES_COMMAND_OK);
1803  ClearOrSaveResult(results);
1804  }
1805  else
1806  PQclear(results);
1807 
1808  if (started_txn)
1809  {
1810  results = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK");
1811  OK &= AcceptResult(results) &&
1812  (PQresultStatus(results) == PGRES_COMMAND_OK);
1813  ClearOrSaveResult(results);
1814  }
1815 
1816  if (pset.timing)
1817  {
1818  INSTR_TIME_SET_CURRENT(after);
1819  INSTR_TIME_SUBTRACT(after, before);
1820  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1821  }
1822 
1823  return OK;
1824 }
char * gset_prefix
Definition: settings.h:96
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:451
void disable_sigpipe_trap(void)
Definition: print.c:2925
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void ClosePager(FILE *pagerpipe)
Definition: print.c:3026
static void SetResultVariables(PGresult *results, bool success)
Definition: common.c:409
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:202
struct timeval instr_time
Definition: instr_time.h:150
bool start_table
Definition: print.h:111
printTableOpt topt
Definition: print.h:169
FILE * queryFout
Definition: settings.h:84
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
unsigned long prior_records
Definition: print.h:114
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
static bool AcceptResult(const PGresult *result)
Definition: common.c:352
static int before(chr x, chr y)
Definition: regc_locale.c:496
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:2975
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static char * buf
Definition: pg_test_fsync.c:67
int fetch_count
Definition: settings.h:131
void restore_sigpipe_trap(void)
Definition: print.c:2948
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6627
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:50
char * gfname
Definition: settings.h:93
static void cleanup(void)
Definition: bootstrap.c:886
FILE * logfile
Definition: settings.h:116
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
void PQclear(PGresult *res)
Definition: fe-exec.c:694
bool stop_table
Definition: print.h:112
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
#define Assert(condition)
Definition: c.h:745
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3417
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
#define INT64_FORMAT
Definition: c.h:416
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:758
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define snprintf
Definition: port.h:193
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
VariableSpace vars
Definition: settings.h:118

◆ expand_tilde()

void expand_tilde ( char **  filename)

Definition at line 2218 of file common.c.

References filename, fn(), free, get_home_path(), MAXPGPATH, psprintf(), and strlcpy().

Referenced by exec_command_edit(), exec_command_g(), exec_command_include(), exec_command_lo(), exec_command_out(), exec_command_s(), exec_command_write(), initializeInput(), parse_slash_copy(), and process_psqlrc().

2219 {
2220  if (!filename || !(*filename))
2221  return;
2222 
2223  /*
2224  * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2225  * for short versions of long file names, though the tilde is usually
2226  * toward the end, not at the beginning.
2227  */
2228 #ifndef WIN32
2229 
2230  /* try tilde expansion */
2231  if (**filename == '~')
2232  {
2233  char *fn;
2234  char oldp,
2235  *p;
2236  struct passwd *pw;
2237  char home[MAXPGPATH];
2238 
2239  fn = *filename;
2240  *home = '\0';
2241 
2242  p = fn + 1;
2243  while (*p != '/' && *p != '\0')
2244  p++;
2245 
2246  oldp = *p;
2247  *p = '\0';
2248 
2249  if (*(fn + 1) == '\0')
2250  get_home_path(home); /* ~ or ~/ only */
2251  else if ((pw = getpwnam(fn + 1)) != NULL)
2252  strlcpy(home, pw->pw_dir, sizeof(home)); /* ~user */
2253 
2254  *p = oldp;
2255  if (strlen(home) != 0)
2256  {
2257  char *newfn;
2258 
2259  newfn = psprintf("%s%s", home, p);
2260  free(fn);
2261  *filename = newfn;
2262  }
2263  }
2264 #endif
2265 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define MAXPGPATH
static void * fn(void *arg)
#define free(a)
Definition: header.h:65
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
static char * filename
Definition: pg_dumpall.c:90
bool get_home_path(char *ret_path)
Definition: path.c:807

◆ is_select_command()

static bool is_select_command ( const char *  query)
static

Definition at line 2110 of file common.c.

References _psqlSettings::encoding, pg_strncasecmp(), PQmblen(), pset, and skip_white_space().

Referenced by SendQuery().

2111 {
2112  int wordlen;
2113 
2114  /*
2115  * First advance over any whitespace, comments and left parentheses.
2116  */
2117  for (;;)
2118  {
2119  query = skip_white_space(query);
2120  if (query[0] == '(')
2121  query++;
2122  else
2123  break;
2124  }
2125 
2126  /*
2127  * Check word length (since "selectx" is not "select").
2128  */
2129  wordlen = 0;
2130  while (isalpha((unsigned char) query[wordlen]))
2131  wordlen += PQmblen(&query[wordlen], pset.encoding);
2132 
2133  if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
2134  return true;
2135 
2136  if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
2137  return true;
2138 
2139  return false;
2140 }
PsqlSettings pset
Definition: startup.c:31
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
int encoding
Definition: settings.h:83
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1221
static const char * skip_white_space(const char *query)
Definition: common.c:1831

◆ is_superuser()

bool is_superuser ( void  )

Definition at line 2150 of file common.c.

References _psqlSettings::db, PQparameterStatus(), pset, and val.

2151 {
2152  const char *val;
2153 
2154  if (!pset.db)
2155  return false;
2156 
2157  val = PQparameterStatus(pset.db, "is_superuser");
2158 
2159  if (val && strcmp(val, "on") == 0)
2160  return true;
2161 
2162  return false;
2163 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6637
long val
Definition: informix.c:664

◆ NoticeProcessor()

void NoticeProcessor ( void *  arg,
const char *  message 
)

Definition at line 220 of file common.c.

References pg_log_info.

Referenced by do_connect(), and main().

221 {
222  (void) arg; /* not used */
223  pg_log_info("%s", message);
224 }
void * arg
#define pg_log_info(...)
Definition: logging.h:87

◆ openQueryOutputFile()

bool openQueryOutputFile ( const char *  fname,
FILE **  fout,
bool is_pipe 
)

Definition at line 50 of file common.c.

References pg_log_error, and generate_unaccent_rules::stdout.

Referenced by ExecQueryUsingCursor(), PrintQueryTuples(), ProcessResult(), and setQFout().

51 {
52  if (!fname || fname[0] == '\0')
53  {
54  *fout = stdout;
55  *is_pipe = false;
56  }
57  else if (*fname == '|')
58  {
59  *fout = popen(fname + 1, "w");
60  *is_pipe = true;
61  }
62  else
63  {
64  *fout = fopen(fname, "w");
65  *is_pipe = false;
66  }
67 
68  if (*fout == NULL)
69  {
70  pg_log_error("%s: %m", fname);
71  return false;
72  }
73 
74  return true;
75 }
#define pg_log_error(...)
Definition: logging.h:79

◆ PrintNotifications()

static void PrintNotifications ( void  )
static

Definition at line 681 of file common.c.

References _, pgNotify::be_pid, _psqlSettings::db, pgNotify::extra, fprintf, PQconsumeInput(), PQfreemem(), PQnotifies(), pset, _psqlSettings::queryFout, and pgNotify::relname.

Referenced by SendQuery().

682 {
683  PGnotify *notify;
684 
686  while ((notify = PQnotifies(pset.db)) != NULL)
687  {
688  /* for backward compatibility, only show payload if nonempty */
689  if (notify->extra[0])
690  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
691  notify->relname, notify->extra, notify->be_pid);
692  else
693  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
694  notify->relname, notify->be_pid);
695  fflush(pset.queryFout);
696  PQfreemem(notify);
698  }
699 }
char * extra
Definition: libpq-fe.h:168
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
PGnotify * PQnotifies(PGconn *conn)
Definition: fe-exec.c:2289
FILE * queryFout
Definition: settings.h:84
#define fprintf
Definition: port.h:197
int be_pid
Definition: libpq-fe.h:167
char * relname
Definition: libpq-fe.h:166
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1704
#define _(x)
Definition: elog.c:88
void PQfreemem(void *ptr)
Definition: fe-exec.c:3296

◆ PrintQueryResults()

static bool PrintQueryResults ( PGresult results)
static

Definition at line 1104 of file common.c.

References _psqlSettings::crosstab_flag, ExecQueryTuples(), _psqlSettings::gexec_flag, _psqlSettings::gset_prefix, pg_log_error, PGRES_BAD_RESPONSE, PGRES_COMMAND_OK, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_NONFATAL_ERROR, PGRES_TUPLES_OK, PQcmdStatus(), PQresultStatus(), PrintQueryStatus(), PrintQueryTuples(), PrintResultsInCrosstab(), pset, _psqlSettings::queryFout, StoreQueryTuple(), and success.

Referenced by DescribeQuery(), and SendQuery().

1105 {
1106  bool success;
1107  const char *cmdstatus;
1108 
1109  if (!results)
1110  return false;
1111 
1112  switch (PQresultStatus(results))
1113  {
1114  case PGRES_TUPLES_OK:
1115  /* store or execute or print the data ... */
1116  if (pset.gset_prefix)
1117  success = StoreQueryTuple(results);
1118  else if (pset.gexec_flag)
1119  success = ExecQueryTuples(results);
1120  else if (pset.crosstab_flag)
1121  success = PrintResultsInCrosstab(results);
1122  else
1123  success = PrintQueryTuples(results);
1124  /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
1125  cmdstatus = PQcmdStatus(results);
1126  if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
1127  strncmp(cmdstatus, "UPDATE", 6) == 0 ||
1128  strncmp(cmdstatus, "DELETE", 6) == 0)
1129  PrintQueryStatus(results);
1130  break;
1131 
1132  case PGRES_COMMAND_OK:
1133  PrintQueryStatus(results);
1134  success = true;
1135  break;
1136 
1137  case PGRES_EMPTY_QUERY:
1138  success = true;
1139  break;
1140 
1141  case PGRES_COPY_OUT:
1142  case PGRES_COPY_IN:
1143  /* nothing to do here */
1144  success = true;
1145  break;
1146 
1147  case PGRES_BAD_RESPONSE:
1148  case PGRES_NONFATAL_ERROR:
1149  case PGRES_FATAL_ERROR:
1150  success = false;
1151  break;
1152 
1153  default:
1154  success = false;
1155  pg_log_error("unexpected PQresultStatus: %d",
1156  PQresultStatus(results));
1157  break;
1158  }
1159 
1160  fflush(pset.queryFout);
1161 
1162  return success;
1163 }
static void PrintQueryStatus(PGresult *results)
Definition: common.c:1072
char * gset_prefix
Definition: settings.h:96
PsqlSettings pset
Definition: startup.c:31
#define pg_log_error(...)
Definition: logging.h:79
static bool ExecQueryTuples(const PGresult *result)
Definition: common.c:815
static bool PrintQueryTuples(const PGresult *results)
Definition: common.c:708
bool gexec_flag
Definition: settings.h:98
FILE * queryFout
Definition: settings.h:84
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
bool PrintResultsInCrosstab(const PGresult *res)
Definition: crosstabview.c:103
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:758
bool crosstab_flag
Definition: settings.h:99
static bool success
Definition: initdb.c:161

◆ PrintQueryStatus()

static void PrintQueryStatus ( PGresult results)
static

Definition at line 1072 of file common.c.

References buf, printTableOpt::format, fprintf, html_escaped_print(), _psqlSettings::logfile, _psqlSettings::popt, PQcmdStatus(), PQoidValue(), PRINT_HTML, pset, _psqlSettings::queryFout, _psqlSettings::quiet, SetVariable(), snprintf, printQueryOpt::topt, and _psqlSettings::vars.

Referenced by PrintQueryResults().

1073 {
1074  char buf[16];
1075 
1076  if (!pset.quiet)
1077  {
1078  if (pset.popt.topt.format == PRINT_HTML)
1079  {
1080  fputs("<p>", pset.queryFout);
1082  fputs("</p>\n", pset.queryFout);
1083  }
1084  else
1085  fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
1086  }
1087 
1088  if (pset.logfile)
1089  fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
1090 
1091  snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
1092  SetVariable(pset.vars, "LASTOID", buf);
1093 }
PsqlSettings pset
Definition: startup.c:31
Oid PQoidValue(const PGresult *res)
Definition: fe-exec.c:3081
enum printFormat format
Definition: print.h:101
printTableOpt topt
Definition: print.h:169
FILE * queryFout
Definition: settings.h:84
#define fprintf
Definition: port.h:197
static char * buf
Definition: pg_test_fsync.c:67
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
FILE * logfile
Definition: settings.h:116
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
printQueryOpt popt
Definition: settings.h:91
void html_escaped_print(const char *in, FILE *fout)
Definition: print.c:1838
#define snprintf
Definition: port.h:193
VariableSpace vars
Definition: settings.h:118

◆ PrintQueryTuples()

static bool PrintQueryTuples ( const PGresult results)
static

Definition at line 708 of file common.c.

References disable_sigpipe_trap(), _psqlSettings::gfname, _psqlSettings::logfile, openQueryOutputFile(), pg_log_error, _psqlSettings::popt, printQuery(), pset, _psqlSettings::queryFout, and restore_sigpipe_trap().

Referenced by PrintQueryResults().

709 {
710  bool result = true;
711 
712  /* write output to \g argument, if any */
713  if (pset.gfname)
714  {
715  FILE *fout;
716  bool is_pipe;
717 
718  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
719  return false;
720  if (is_pipe)
722 
723  printQuery(results, &pset.popt, fout, false, pset.logfile);
724  if (ferror(fout))
725  {
726  pg_log_error("could not print result table: %m");
727  result = false;
728  }
729 
730  if (is_pipe)
731  {
732  pclose(fout);
734  }
735  else
736  fclose(fout);
737  }
738  else
739  {
740  printQuery(results, &pset.popt, pset.queryFout, false, pset.logfile);
741  if (ferror(pset.queryFout))
742  {
743  pg_log_error("could not print result table: %m");
744  result = false;
745  }
746  }
747 
748  return result;
749 }
PsqlSettings pset
Definition: startup.c:31
void disable_sigpipe_trap(void)
Definition: print.c:2925
#define pg_log_error(...)
Definition: logging.h:79
FILE * queryFout
Definition: settings.h:84
void restore_sigpipe_trap(void)
Definition: print.c:2948
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:50
char * gfname
Definition: settings.h:93
FILE * logfile
Definition: settings.h:116
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3417

◆ PrintTiming()

static void PrintTiming ( double  elapsed_msec)
static

Definition at line 477 of file common.c.

References _, days, and printf.

Referenced by PSQLexecWatch(), and SendQuery().

478 {
479  double seconds;
480  double minutes;
481  double hours;
482  double days;
483 
484  if (elapsed_msec < 1000.0)
485  {
486  /* This is the traditional (pre-v10) output format */
487  printf(_("Time: %.3f ms\n"), elapsed_msec);
488  return;
489  }
490 
491  /*
492  * Note: we could print just seconds, in a format like %06.3f, when the
493  * total is less than 1min. But that's hard to interpret unless we tack
494  * on "s" or otherwise annotate it. Forcing the display to include
495  * minutes seems like a better solution.
496  */
497  seconds = elapsed_msec / 1000.0;
498  minutes = floor(seconds / 60.0);
499  seconds -= 60.0 * minutes;
500  if (minutes < 60.0)
501  {
502  printf(_("Time: %.3f ms (%02d:%06.3f)\n"),
503  elapsed_msec, (int) minutes, seconds);
504  return;
505  }
506 
507  hours = floor(minutes / 60.0);
508  minutes -= 60.0 * hours;
509  if (hours < 24.0)
510  {
511  printf(_("Time: %.3f ms (%02d:%02d:%06.3f)\n"),
512  elapsed_msec, (int) hours, (int) minutes, seconds);
513  return;
514  }
515 
516  days = floor(hours / 24.0);
517  hours -= 24.0 * days;
518  printf(_("Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n"),
519  elapsed_msec, days, (int) hours, (int) minutes, seconds);
520 }
#define printf(...)
Definition: port.h:199
const char *const days[]
Definition: datetime.c:68
#define _(x)
Definition: elog.c:88

◆ ProcessResult()

static bool ProcessResult ( PGresult **  results)
static

Definition at line 899 of file common.c.

References AcceptResult(), CheckConnection(), _psqlSettings::copyStream, _psqlSettings::cur_cmd_source, _psqlSettings::db, disable_sigpipe_trap(), _psqlSettings::gfname, handleCopyIn(), handleCopyOut(), openQueryOutputFile(), pg_log_error, PGRES_COMMAND_OK, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_TUPLES_OK, PQbinaryTuples(), PQclear(), PQgetResult(), PQresultStatus(), pset, _psqlSettings::queryFout, ResetCancelConn(), restore_sigpipe_trap(), SetCancelConn(), SetResultVariables(), and success.

Referenced by SendQuery().

900 {
901  bool success = true;
902  bool first_cycle = true;
903 
904  for (;;)
905  {
906  ExecStatusType result_status;
907  bool is_copy;
908  PGresult *next_result;
909 
910  if (!AcceptResult(*results))
911  {
912  /*
913  * Failure at this point is always a server-side failure or a
914  * failure to submit the command string. Either way, we're
915  * finished with this command string.
916  */
917  success = false;
918  break;
919  }
920 
921  result_status = PQresultStatus(*results);
922  switch (result_status)
923  {
924  case PGRES_EMPTY_QUERY:
925  case PGRES_COMMAND_OK:
926  case PGRES_TUPLES_OK:
927  is_copy = false;
928  break;
929 
930  case PGRES_COPY_OUT:
931  case PGRES_COPY_IN:
932  is_copy = true;
933  break;
934 
935  default:
936  /* AcceptResult() should have caught anything else. */
937  is_copy = false;
938  pg_log_error("unexpected PQresultStatus: %d", result_status);
939  break;
940  }
941 
942  if (is_copy)
943  {
944  /*
945  * Marshal the COPY data. Either subroutine will get the
946  * connection out of its COPY state, then call PQresultStatus()
947  * once and report any error.
948  *
949  * For COPY OUT, direct the output to pset.copyStream if it's set,
950  * otherwise to pset.gfname if it's set, otherwise to queryFout.
951  * For COPY IN, use pset.copyStream as data source if it's set,
952  * otherwise cur_cmd_source.
953  */
954  FILE *copystream;
955  PGresult *copy_result;
956 
958  if (result_status == PGRES_COPY_OUT)
959  {
960  bool need_close = false;
961  bool is_pipe = false;
962 
963  if (pset.copyStream)
964  {
965  /* invoked by \copy */
966  copystream = pset.copyStream;
967  }
968  else if (pset.gfname)
969  {
970  /* invoked by \g */
972  &copystream, &is_pipe))
973  {
974  need_close = true;
975  if (is_pipe)
977  }
978  else
979  copystream = NULL; /* discard COPY data entirely */
980  }
981  else
982  {
983  /* fall back to the generic query output stream */
984  copystream = pset.queryFout;
985  }
986 
987  success = handleCopyOut(pset.db,
988  copystream,
989  &copy_result)
990  && success
991  && (copystream != NULL);
992 
993  /*
994  * Suppress status printing if the report would go to the same
995  * place as the COPY data just went. Note this doesn't
996  * prevent error reporting, since handleCopyOut did that.
997  */
998  if (copystream == pset.queryFout)
999  {
1000  PQclear(copy_result);
1001  copy_result = NULL;
1002  }
1003 
1004  if (need_close)
1005  {
1006  /* close \g argument file/pipe */
1007  if (is_pipe)
1008  {
1009  pclose(copystream);
1011  }
1012  else
1013  {
1014  fclose(copystream);
1015  }
1016  }
1017  }
1018  else
1019  {
1020  /* COPY IN */
1021  copystream = pset.copyStream ? pset.copyStream : pset.cur_cmd_source;
1022  success = handleCopyIn(pset.db,
1023  copystream,
1024  PQbinaryTuples(*results),
1025  &copy_result) && success;
1026  }
1027  ResetCancelConn();
1028 
1029  /*
1030  * Replace the PGRES_COPY_OUT/IN result with COPY command's exit
1031  * status, or with NULL if we want to suppress printing anything.
1032  */
1033  PQclear(*results);
1034  *results = copy_result;
1035  }
1036  else if (first_cycle)
1037  {
1038  /* fast path: no COPY commands; PQexec visited all results */
1039  break;
1040  }
1041 
1042  /*
1043  * Check PQgetResult() again. In the typical case of a single-command
1044  * string, it will return NULL. Otherwise, we'll have other results
1045  * to process that may include other COPYs. We keep the last result.
1046  */
1047  next_result = PQgetResult(pset.db);
1048  if (!next_result)
1049  break;
1050 
1051  PQclear(*results);
1052  *results = next_result;
1053  first_cycle = false;
1054  }
1055 
1056  SetResultVariables(*results, success);
1057 
1058  /* may need this to recover from conn loss during COPY */
1059  if (!first_cycle && !CheckConnection())
1060  return false;
1061 
1062  return success;
1063 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
void disable_sigpipe_trap(void)
Definition: print.c:2925
#define pg_log_error(...)
Definition: logging.h:79
void ResetCancelConn(void)
Definition: cancel.c:100
static void SetResultVariables(PGresult *results, bool success)
Definition: common.c:409
FILE * queryFout
Definition: settings.h:84
static bool CheckConnection(void)
Definition: common.c:295
ExecStatusType
Definition: libpq-fe.h:84
int PQbinaryTuples(const PGresult *res)
Definition: fe-exec.c:2785
FILE * copyStream
Definition: settings.h:87
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
FILE * cur_cmd_source
Definition: settings.h:105
static bool AcceptResult(const PGresult *result)
Definition: common.c:352
bool handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res)
Definition: copy.c:436
void SetCancelConn(PGconn *conn)
Definition: cancel.c:70
void restore_sigpipe_trap(void)
Definition: print.c:2948
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:50
char * gfname
Definition: settings.h:93
void PQclear(PGresult *res)
Definition: fe-exec.c:694
bool handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
Definition: copy.c:513
static bool success
Definition: initdb.c:161
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1778

◆ psql_cancel_callback()

static void psql_cancel_callback ( void  )
static

Definition at line 250 of file common.c.

References cancel_pressed, sigint_interrupt_enabled, and sigint_interrupt_jmp.

Referenced by psql_setup_cancel_handler().

251 {
252 #ifndef WIN32
253  /* if we are waiting for input, longjmp out of it */
255  {
256  sigint_interrupt_enabled = false;
257  siglongjmp(sigint_interrupt_jmp, 1);
258  }
259 #endif
260 
261  /* else, set cancel flag to stop any long-running loops */
262  cancel_pressed = true;
263 }
volatile bool sigint_interrupt_enabled
Definition: common.c:245
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:247
volatile sig_atomic_t cancel_pressed
Definition: print.c:43

◆ psql_get_variable()

char* psql_get_variable ( const char *  varname,
PsqlScanQuoteType  quote,
void *  passthrough 
)

Definition at line 129 of file common.c.

References appendShellStringNoError(), buf, conditional_active(), PQExpBufferData::data, _psqlSettings::db, error(), free, GetVariable(), initPQExpBuffer(), pg_log_error, pg_log_info, pg_strdup(), PQerrorMessage(), PQescapeIdentifier(), PQescapeLiteral(), PQfreemem(), PQUOTE_PLAIN, PQUOTE_SHELL_ARG, PQUOTE_SQL_IDENT, PQUOTE_SQL_LITERAL, pset, value, and _psqlSettings::vars.

131 {
132  char *result = NULL;
133  const char *value;
134 
135  /* In an inactive \if branch, suppress all variable substitutions */
136  if (passthrough && !conditional_active((ConditionalStack) passthrough))
137  return NULL;
138 
139  value = GetVariable(pset.vars, varname);
140  if (!value)
141  return NULL;
142 
143  switch (quote)
144  {
145  case PQUOTE_PLAIN:
146  result = pg_strdup(value);
147  break;
148  case PQUOTE_SQL_LITERAL:
149  case PQUOTE_SQL_IDENT:
150  {
151  /*
152  * For these cases, we use libpq's quoting functions, which
153  * assume the string is in the connection's client encoding.
154  */
155  char *escaped_value;
156 
157  if (!pset.db)
158  {
159  pg_log_error("cannot escape without active connection");
160  return NULL;
161  }
162 
163  if (quote == PQUOTE_SQL_LITERAL)
164  escaped_value =
165  PQescapeLiteral(pset.db, value, strlen(value));
166  else
167  escaped_value =
168  PQescapeIdentifier(pset.db, value, strlen(value));
169 
170  if (escaped_value == NULL)
171  {
172  const char *error = PQerrorMessage(pset.db);
173 
174  pg_log_info("%s", error);
175  return NULL;
176  }
177 
178  /*
179  * Rather than complicate the lexer's API with a notion of
180  * which free() routine to use, just pay the price of an extra
181  * strdup().
182  */
183  result = pg_strdup(escaped_value);
184  PQfreemem(escaped_value);
185  break;
186  }
187  case PQUOTE_SHELL_ARG:
188  {
189  /*
190  * For this we use appendShellStringNoError, which is
191  * encoding-agnostic, which is fine since the shell probably
192  * is too. In any case, the only special character is "'",
193  * which is not known to appear in valid multibyte characters.
194  */
196 
197  initPQExpBuffer(&buf);
198  if (!appendShellStringNoError(&buf, value))
199  {
200  pg_log_error("shell command argument contains a newline or carriage return: \"%s\"",
201  value);
202  free(buf.data);
203  return NULL;
204  }
205  result = buf.data;
206  break;
207  }
208 
209  /* No default: we want a compiler warning for missing cases */
210  }
211 
212  return result;
213 }
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:128
PsqlSettings pset
Definition: startup.c:31
static void error(void)
Definition: sql-dyntest.c:147
#define pg_log_error(...)
Definition: logging.h:79
bool appendShellStringNoError(PQExpBuffer buf, const char *str)
Definition: string_utils.c:441
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3570
static char * buf
Definition: pg_test_fsync.c:67
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
const char * GetVariable(VariableSpace space, const char *name)
Definition: variables.c:71
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3564
static struct @143 value
#define free(a)
Definition: header.h:65
void PQfreemem(void *ptr)
Definition: fe-exec.c:3296
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
#define pg_log_info(...)
Definition: logging.h:87
VariableSpace vars
Definition: settings.h:118

◆ psql_setup_cancel_handler()

void psql_setup_cancel_handler ( void  )

Definition at line 266 of file common.c.

References psql_cancel_callback(), and setup_cancel_handler().

Referenced by main().

267 {
269 }
static void setup_cancel_handler(void)
Definition: parallel.c:627
static void psql_cancel_callback(void)
Definition: common.c:250

◆ PSQLexec()

PGresult* PSQLexec ( const char *  query)

Definition at line 536 of file common.c.

References _, AcceptResult(), ClearOrSaveResult(), _psqlSettings::db, _psqlSettings::echo_hidden, fprintf, _psqlSettings::logfile, pg_log_error, PQexec(), printf, pset, PSQL_ECHO_HIDDEN_NOEXEC, PSQL_ECHO_HIDDEN_OFF, ResetCancelConn(), SetCancelConn(), and generate_unaccent_rules::stdout.

Referenced by add_tablespace_footer(), describeAccessMethods(), describeAggregates(), describeFunctions(), describeOneTableDetails(), describeOneTSConfig(), describeOneTSParser(), describeOperators(), describePublications(), describeRoles(), describeSubscriptions(), describeTableDetails(), describeTablespaces(), describeTypes(), do_lo_import(), do_lo_list(), exec_command_password(), fail_lo_xact(), finish_lo_xact(), listAllDbs(), listCasts(), listCollations(), listConversions(), listDbRoleSettings(), listDefaultACLs(), listDomains(), listEventTriggers(), listExtensionContents(), listExtensions(), listForeignDataWrappers(), listForeignServers(), listForeignTables(), listLanguages(), listOneExtensionContents(), listOperatorClasses(), listOperatorFamilies(), listOpFamilyFunctions(), listOpFamilyOperators(), listPartitionedTables(), listPublications(), listSchemas(), listTables(), listTSConfigs(), listTSConfigsVerbose(), listTSDictionaries(), listTSParsers(), listTSParsersVerbose(), listTSTemplates(), listUserMappings(), main(), objectDescription(), permissionsList(), and start_lo_xact().

537 {
538  PGresult *res;
539 
540  if (!pset.db)
541  {
542  pg_log_error("You are currently not connected to a database.");
543  return NULL;
544  }
545 
547  {
548  printf(_("********* QUERY **********\n"
549  "%s\n"
550  "**************************\n\n"), query);
551  fflush(stdout);
552  if (pset.logfile)
553  {
555  _("********* QUERY **********\n"
556  "%s\n"
557  "**************************\n\n"), query);
558  fflush(pset.logfile);
559  }
560 
562  return NULL;
563  }
564 
566 
567  res = PQexec(pset.db, query);
568 
569  ResetCancelConn();
570 
571  if (!AcceptResult(res))
572  {
573  ClearOrSaveResult(res);
574  res = NULL;
575  }
576 
577  return res;
578 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:451
#define pg_log_error(...)
Definition: logging.h:79
void ResetCancelConn(void)
Definition: cancel.c:100
#define printf(...)
Definition: port.h:199
#define fprintf
Definition: port.h:197
static bool AcceptResult(const PGresult *result)
Definition: common.c:352
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:135
void SetCancelConn(PGconn *conn)
Definition: cancel.c:70
FILE * logfile
Definition: settings.h:116
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define _(x)
Definition: elog.c:88

◆ PSQLexecWatch()

int PSQLexecWatch ( const char *  query,
const printQueryOpt opt 
)

Definition at line 591 of file common.c.

References AcceptResult(), before(), cancel_pressed, ClearOrSaveResult(), _psqlSettings::db, fprintf, INSTR_TIME_GET_MILLISEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SUBTRACT, _psqlSettings::logfile, pg_log_error, PGRES_COMMAND_OK, PGRES_COPY_BOTH, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_TUPLES_OK, PQclear(), PQcmdStatus(), PQexec(), PQresultStatus(), printQuery(), PrintTiming(), pset, _psqlSettings::queryFout, ResetCancelConn(), SetCancelConn(), _psqlSettings::timing, and printQueryOpt::title.

Referenced by do_watch().

592 {
593  PGresult *res;
594  double elapsed_msec = 0;
596  instr_time after;
597 
598  if (!pset.db)
599  {
600  pg_log_error("You are currently not connected to a database.");
601  return 0;
602  }
603 
605 
606  if (pset.timing)
607  INSTR_TIME_SET_CURRENT(before);
608 
609  res = PQexec(pset.db, query);
610 
611  ResetCancelConn();
612 
613  if (!AcceptResult(res))
614  {
615  ClearOrSaveResult(res);
616  return 0;
617  }
618 
619  if (pset.timing)
620  {
621  INSTR_TIME_SET_CURRENT(after);
622  INSTR_TIME_SUBTRACT(after, before);
623  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
624  }
625 
626  /*
627  * If SIGINT is sent while the query is processing, the interrupt will be
628  * consumed. The user's intention, though, is to cancel the entire watch
629  * process, so detect a sent cancellation request and exit in this case.
630  */
631  if (cancel_pressed)
632  {
633  PQclear(res);
634  return 0;
635  }
636 
637  switch (PQresultStatus(res))
638  {
639  case PGRES_TUPLES_OK:
640  printQuery(res, opt, pset.queryFout, false, pset.logfile);
641  break;
642 
643  case PGRES_COMMAND_OK:
644  fprintf(pset.queryFout, "%s\n%s\n\n", opt->title, PQcmdStatus(res));
645  break;
646 
647  case PGRES_EMPTY_QUERY:
648  pg_log_error("\\watch cannot be used with an empty query");
649  PQclear(res);
650  return -1;
651 
652  case PGRES_COPY_OUT:
653  case PGRES_COPY_IN:
654  case PGRES_COPY_BOTH:
655  pg_log_error("\\watch cannot be used with COPY");
656  PQclear(res);
657  return -1;
658 
659  default:
660  pg_log_error("unexpected result status for \\watch");
661  PQclear(res);
662  return -1;
663  }
664 
665  PQclear(res);
666 
667  fflush(pset.queryFout);
668 
669  /* Possible microtiming output */
670  if (pset.timing)
671  PrintTiming(elapsed_msec);
672 
673  return 1;
674 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:451
#define pg_log_error(...)
Definition: logging.h:79
void ResetCancelConn(void)
Definition: cancel.c:100
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:202
struct timeval instr_time
Definition: instr_time.h:150
static void PrintTiming(double elapsed_msec)
Definition: common.c:477
FILE * queryFout
Definition: settings.h:84
#define fprintf
Definition: port.h:197
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
static bool AcceptResult(const PGresult *result)
Definition: common.c:352
static int before(chr x, chr y)
Definition: regc_locale.c:496
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
void SetCancelConn(PGconn *conn)
Definition: cancel.c:70
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
FILE * logfile
Definition: settings.h:116
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
void PQclear(PGresult *res)
Definition: fe-exec.c:694
char * title
Definition: print.h:171
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3417
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ recognized_connection_string()

static bool recognized_connection_string ( const char *  connstr)

Definition at line 2303 of file common.c.

References uri_prefix_length().

Referenced by do_connect().

2304 {
2305  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
2306 }
static int uri_prefix_length(const char *connstr)
Definition: common.c:2276
static char * connstr
Definition: pg_dumpall.c:61

◆ SendQuery()

bool SendQuery ( const char *  query)

Definition at line 1179 of file common.c.

References _, _psqlSettings::autocommit, before(), buf, cancel_pressed, ClearOrSaveResult(), command_no_begin(), ConnectionUp(), _psqlSettings::crosstab_flag, _psqlSettings::ctv_args, _psqlSettings::cur_cmd_interactive, _psqlSettings::db, DescribeQuery(), _psqlSettings::echo, _psqlSettings::encoding, printTableOpt::encoding, ExecQueryUsingCursor(), _psqlSettings::fetch_count, formatPGVersionNumber(), fprintf, free, _psqlSettings::gdesc_flag, _psqlSettings::gexec_flag, _psqlSettings::gfname, _psqlSettings::gsavepopt, _psqlSettings::gset_prefix, i, INSTR_TIME_GET_MILLISEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SUBTRACT, is_select_command(), lengthof, _psqlSettings::logfile, _psqlSettings::on_error_rollback, pg_encoding_to_char(), pg_free(), pg_log_error, pg_log_info, pg_log_warning, PGRES_COMMAND_OK, _psqlSettings::popt, PQclear(), PQclientEncoding(), PQcmdStatus(), PQerrorMessage(), PQexec(), PQresultStatus(), PQTRANS_ACTIVE, PQTRANS_IDLE, PQTRANS_INERROR, PQTRANS_INTRANS, PQTRANS_UNKNOWN, PQtransactionStatus(), printf, PrintNotifications(), PrintQueryResults(), PrintTiming(), ProcessResult(), pset, PSQL_ECHO_ERRORS, PSQL_ECHO_QUERIES, PSQL_ERROR_ROLLBACK_OFF, PSQL_ERROR_ROLLBACK_ON, ResetCancelConn(), restorePsetInfo(), SetCancelConn(), SetVariable(), _psqlSettings::singlestep, generate_unaccent_rules::stdout, _psqlSettings::sversion, _psqlSettings::timing, printQueryOpt::topt, and _psqlSettings::vars.

Referenced by do_copy(), ExecQueryTuples(), main(), and MainLoop().

1180 {
1181  PGresult *results;
1182  PGTransactionStatusType transaction_status;
1183  double elapsed_msec = 0;
1184  bool OK = false;
1185  int i;
1186  bool on_error_rollback_savepoint = false;
1187  static bool on_error_rollback_warning = false;
1188 
1189  if (!pset.db)
1190  {
1191  pg_log_error("You are currently not connected to a database.");
1192  goto sendquery_cleanup;
1193  }
1194 
1195  if (pset.singlestep)
1196  {
1197  char buf[3];
1198 
1199  fflush(stderr);
1200  printf(_("***(Single step mode: verify command)*******************************************\n"
1201  "%s\n"
1202  "***(press return to proceed or enter x and return to cancel)********************\n"),
1203  query);
1204  fflush(stdout);
1205  if (fgets(buf, sizeof(buf), stdin) != NULL)
1206  if (buf[0] == 'x')
1207  goto sendquery_cleanup;
1208  if (cancel_pressed)
1209  goto sendquery_cleanup;
1210  }
1211  else if (pset.echo == PSQL_ECHO_QUERIES)
1212  {
1213  puts(query);
1214  fflush(stdout);
1215  }
1216 
1217  if (pset.logfile)
1218  {
1220  _("********* QUERY **********\n"
1221  "%s\n"
1222  "**************************\n\n"), query);
1223  fflush(pset.logfile);
1224  }
1225 
1227 
1228  transaction_status = PQtransactionStatus(pset.db);
1229 
1230  if (transaction_status == PQTRANS_IDLE &&
1231  !pset.autocommit &&
1232  !command_no_begin(query))
1233  {
1234  results = PQexec(pset.db, "BEGIN");
1235  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1236  {
1238  ClearOrSaveResult(results);
1239  ResetCancelConn();
1240  goto sendquery_cleanup;
1241  }
1242  ClearOrSaveResult(results);
1243  transaction_status = PQtransactionStatus(pset.db);
1244  }
1245 
1246  if (transaction_status == PQTRANS_INTRANS &&
1250  {
1251  if (on_error_rollback_warning == false && pset.sversion < 80000)
1252  {
1253  char sverbuf[32];
1254 
1255  pg_log_warning("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.",
1257  sverbuf, sizeof(sverbuf)));
1258  on_error_rollback_warning = true;
1259  }
1260  else
1261  {
1262  results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
1263  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1264  {
1266  ClearOrSaveResult(results);
1267  ResetCancelConn();
1268  goto sendquery_cleanup;
1269  }
1270  ClearOrSaveResult(results);
1271  on_error_rollback_savepoint = true;
1272  }
1273  }
1274 
1275  if (pset.gdesc_flag)
1276  {
1277  /* Describe query's result columns, without executing it */
1278  OK = DescribeQuery(query, &elapsed_msec);
1279  ResetCancelConn();
1280  results = NULL; /* PQclear(NULL) does nothing */
1281  }
1282  else if (pset.fetch_count <= 0 || pset.gexec_flag ||
1284  {
1285  /* Default fetch-it-all-and-print mode */
1287  after;
1288 
1289  if (pset.timing)
1290  INSTR_TIME_SET_CURRENT(before);
1291 
1292  results = PQexec(pset.db, query);
1293 
1294  /* these operations are included in the timing result: */
1295  ResetCancelConn();
1296  OK = ProcessResult(&results);
1297 
1298  if (pset.timing)
1299  {
1300  INSTR_TIME_SET_CURRENT(after);
1301  INSTR_TIME_SUBTRACT(after, before);
1302  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1303  }
1304 
1305  /* but printing results isn't: */
1306  if (OK && results)
1307  OK = PrintQueryResults(results);
1308  }
1309  else
1310  {
1311  /* Fetch-in-segments mode */
1312  OK = ExecQueryUsingCursor(query, &elapsed_msec);
1313  ResetCancelConn();
1314  results = NULL; /* PQclear(NULL) does nothing */
1315  }
1316 
1317  if (!OK && pset.echo == PSQL_ECHO_ERRORS)
1318  pg_log_info("STATEMENT: %s", query);
1319 
1320  /* If we made a temporary savepoint, possibly release/rollback */
1321  if (on_error_rollback_savepoint)
1322  {
1323  const char *svptcmd = NULL;
1324 
1325  transaction_status = PQtransactionStatus(pset.db);
1326 
1327  switch (transaction_status)
1328  {
1329  case PQTRANS_INERROR:
1330  /* We always rollback on an error */
1331  svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
1332  break;
1333 
1334  case PQTRANS_IDLE:
1335  /* If they are no longer in a transaction, then do nothing */
1336  break;
1337 
1338  case PQTRANS_INTRANS:
1339 
1340  /*
1341  * Do nothing if they are messing with savepoints themselves:
1342  * If the user did RELEASE or ROLLBACK, our savepoint is gone.
1343  * If they issued a SAVEPOINT, releasing ours would remove
1344  * theirs.
1345  */
1346  if (results &&
1347  (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
1348  strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
1349  strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
1350  svptcmd = NULL;
1351  else
1352  svptcmd = "RELEASE pg_psql_temporary_savepoint";
1353  break;
1354 
1355  case PQTRANS_ACTIVE:
1356  case PQTRANS_UNKNOWN:
1357  default:
1358  OK = false;
1359  /* PQTRANS_UNKNOWN is expected given a broken connection. */
1360  if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp())
1361  pg_log_error("unexpected transaction status (%d)",
1362  transaction_status);
1363  break;
1364  }
1365 
1366  if (svptcmd)
1367  {
1368  PGresult *svptres;
1369 
1370  svptres = PQexec(pset.db, svptcmd);
1371  if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
1372  {
1374  ClearOrSaveResult(svptres);
1375  OK = false;
1376 
1377  PQclear(results);
1378  ResetCancelConn();
1379  goto sendquery_cleanup;
1380  }
1381  PQclear(svptres);
1382  }
1383  }
1384 
1385  ClearOrSaveResult(results);
1386 
1387  /* Possible microtiming output */
1388  if (pset.timing)
1389  PrintTiming(elapsed_msec);
1390 
1391  /* check for events that may occur during query execution */
1392 
1393  if (pset.encoding != PQclientEncoding(pset.db) &&
1394  PQclientEncoding(pset.db) >= 0)
1395  {
1396  /* track effects of SET CLIENT_ENCODING */
1399  SetVariable(pset.vars, "ENCODING",
1401  }
1402 
1404 
1405  /* perform cleanup that should occur after any attempted query */
1406 
1407 sendquery_cleanup:
1408 
1409  /* reset \g's output-to-filename trigger */
1410  if (pset.gfname)
1411  {
1412  free(pset.gfname);
1413  pset.gfname = NULL;
1414  }
1415 
1416  /* restore print settings if \g changed them */
1417  if (pset.gsavepopt)
1418  {
1420  pset.gsavepopt = NULL;
1421  }
1422 
1423  /* reset \gset trigger */
1424  if (pset.gset_prefix)
1425  {
1427  pset.gset_prefix = NULL;
1428  }
1429 
1430  /* reset \gdesc trigger */
1431  pset.gdesc_flag = false;
1432 
1433  /* reset \gexec trigger */
1434  pset.gexec_flag = false;
1435 
1436  /* reset \crosstabview trigger */
1437  pset.crosstab_flag = false;
1438  for (i = 0; i < lengthof(pset.ctv_args); i++)
1439  {
1440  pg_free(pset.ctv_args[i]);
1441  pset.ctv_args[i] = NULL;
1442  }
1443 
1444  return OK;
1445 }
PSQL_ECHO echo
Definition: settings.h:134
bool singlestep
Definition: settings.h:129
char * gset_prefix
Definition: settings.h:96
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1104
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
int encoding
Definition: print.h:122
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:451
#define pg_log_error(...)
Definition: logging.h:79
void ResetCancelConn(void)
Definition: cancel.c:100
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:202
struct timeval instr_time
Definition: instr_time.h:150
bool gexec_flag
Definition: settings.h:98
printTableOpt topt
Definition: print.h:169
static void PrintTiming(double elapsed_msec)
Definition: common.c:477
printQueryOpt * gsavepopt
Definition: settings.h:94
#define printf(...)
Definition: port.h:199
static bool ConnectionUp(void)
Definition: common.c:277
bool autocommit
Definition: settings.h:125
#define lengthof(array)
Definition: c.h:675
#define fprintf
Definition: port.h:197
PSQL_ERROR_ROLLBACK on_error_rollback
Definition: settings.h:136
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6732
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
static void PrintNotifications(void)
Definition: common.c:681
char * ctv_args[4]
Definition: settings.h:100
static int before(chr x, chr y)
Definition: regc_locale.c:496
bool cur_cmd_interactive
Definition: settings.h:107
static bool is_select_command(const char *query)
Definition: common.c:2110
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
Definition: command.c:4456
bool gdesc_flag
Definition: settings.h:97
static char * buf
Definition: pg_test_fsync.c:67
int fetch_count
Definition: settings.h:131
static bool ProcessResult(PGresult **results)
Definition: common.c:899
void SetCancelConn(PGconn *conn)
Definition: cancel.c:70
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1573
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6627
static bool DescribeQuery(const char *query, double *elapsed_msec)
Definition: common.c:1457
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
char * gfname
Definition: settings.h:93
FILE * logfile
Definition: settings.h:116
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
PGTransactionStatusType
Definition: libpq-fe.h:103
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
printQueryOpt popt
Definition: settings.h:91
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
int i
bool crosstab_flag
Definition: settings.h:99
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define pg_log_warning(...)
Definition: pgfnames.c:24
int encoding
Definition: settings.h:83
static bool command_no_begin(const char *query)
Definition: common.c:1895
#define _(x)
Definition: elog.c:88
#define pg_log_info(...)
Definition: logging.h:87
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:177
VariableSpace vars
Definition: settings.h:118

◆ session_username()

const char* session_username ( void  )

Definition at line 2197 of file common.c.

References _psqlSettings::db, PQparameterStatus(), PQuser(), pset, and val.

Referenced by get_prompt().

2198 {
2199  const char *val;
2200 
2201  if (!pset.db)
2202  return NULL;
2203 
2204  val = PQparameterStatus(pset.db, "session_authorization");
2205  if (val)
2206  return val;
2207  else
2208  return PQuser(pset.db);
2209 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6637
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6530
long val
Definition: informix.c:664

◆ setQFout()

bool setQFout ( const char *  fname)

Definition at line 85 of file common.c.

References openQueryOutputFile(), pset, _psqlSettings::queryFout, _psqlSettings::queryFoutPipe, restore_sigpipe_trap(), set_sigpipe_trap_state(), and generate_unaccent_rules::stdout.

Referenced by exec_command_out(), main(), and parse_psql_options().

86 {
87  FILE *fout;
88  bool is_pipe;
89 
90  /* First make sure we can open the new output file/pipe */
91  if (!openQueryOutputFile(fname, &fout, &is_pipe))
92  return false;
93 
94  /* Close old file/pipe */
95  if (pset.queryFout && pset.queryFout != stdout && pset.queryFout != stderr)
96  {
97  if (pset.queryFoutPipe)
98  pclose(pset.queryFout);
99  else
100  fclose(pset.queryFout);
101  }
102 
103  pset.queryFout = fout;
104  pset.queryFoutPipe = is_pipe;
105 
106  /* Adjust SIGPIPE handling appropriately: ignore signal if is_pipe */
107  set_sigpipe_trap_state(is_pipe);
109 
110  return true;
111 }
PsqlSettings pset
Definition: startup.c:31
bool queryFoutPipe
Definition: settings.h:85
FILE * queryFout
Definition: settings.h:84
void set_sigpipe_trap_state(bool ignore)
Definition: print.c:2961
void restore_sigpipe_trap(void)
Definition: print.c:2948
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:50

◆ SetResultVariables()

static void SetResultVariables ( PGresult results,
bool  success 
)
static

Definition at line 409 of file common.c.

References PG_DIAG_MESSAGE_PRIMARY, PG_DIAG_SQLSTATE, PQcmdTuples(), PQresultErrorField(), pset, SetVariable(), and _psqlSettings::vars.

Referenced by DescribeQuery(), ExecQueryUsingCursor(), and ProcessResult().

410 {
411  if (success)
412  {
413  const char *ntuples = PQcmdTuples(results);
414 
415  SetVariable(pset.vars, "ERROR", "false");
416  SetVariable(pset.vars, "SQLSTATE", "00000");
417  SetVariable(pset.vars, "ROW_COUNT", *ntuples ? ntuples : "0");
418  }
419  else
420  {
421  const char *code = PQresultErrorField(results, PG_DIAG_SQLSTATE);
422  const char *mesg = PQresultErrorField(results, PG_DIAG_MESSAGE_PRIMARY);
423 
424  SetVariable(pset.vars, "ERROR", "true");
425 
426  /*
427  * If there is no SQLSTATE code, use an empty string. This can happen
428  * for libpq-detected errors (e.g., lost connection, ENOMEM).
429  */
430  if (code == NULL)
431  code = "";
432  SetVariable(pset.vars, "SQLSTATE", code);
433  SetVariable(pset.vars, "ROW_COUNT", "0");
434  SetVariable(pset.vars, "LAST_ERROR_SQLSTATE", code);
435  SetVariable(pset.vars, "LAST_ERROR_MESSAGE", mesg ? mesg : "");
436  }
437 }
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
PsqlSettings pset
Definition: startup.c:31
char * PQcmdTuples(PGresult *res)
Definition: fe-exec.c:3110
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2754
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
static bool success
Definition: initdb.c:161
VariableSpace vars
Definition: settings.h:118

◆ skip_white_space()

static const char* skip_white_space ( const char *  query)
static

Definition at line 1831 of file common.c.

References _psqlSettings::encoding, PQmblen(), and pset.

Referenced by command_no_begin(), and is_select_command().

1832 {
1833  int cnestlevel = 0; /* slash-star comment nest level */
1834 
1835  while (*query)
1836  {
1837  int mblen = PQmblen(query, pset.encoding);
1838 
1839  /*
1840  * Note: we assume the encoding is a superset of ASCII, so that for
1841  * example "query[0] == '/'" is meaningful. However, we do NOT assume
1842  * that the second and subsequent bytes of a multibyte character
1843  * couldn't look like ASCII characters; so it is critical to advance
1844  * by mblen, not 1, whenever we haven't exactly identified the
1845  * character we are skipping over.
1846  */
1847  if (isspace((unsigned char) *query))
1848  query += mblen;
1849  else if (query[0] == '/' && query[1] == '*')
1850  {
1851  cnestlevel++;
1852  query += 2;
1853  }
1854  else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
1855  {
1856  cnestlevel--;
1857  query += 2;
1858  }
1859  else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
1860  {
1861  query += 2;
1862 
1863  /*
1864  * We have to skip to end of line since any slash-star inside the
1865  * -- comment does NOT start a slash-star comment.
1866  */
1867  while (*query)
1868  {
1869  if (*query == '\n')
1870  {
1871  query++;
1872  break;
1873  }
1874  query += PQmblen(query, pset.encoding);
1875  }
1876  }
1877  else if (cnestlevel > 0)
1878  query += mblen;
1879  else
1880  break; /* found first token */
1881  }
1882 
1883  return query;
1884 }
PsqlSettings pset
Definition: startup.c:31
int encoding
Definition: settings.h:83
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1221

◆ standard_strings()

bool standard_strings ( void  )

Definition at line 2173 of file common.c.

References _psqlSettings::db, PQparameterStatus(), pset, and val.

Referenced by get_create_object_cmd(), main(), MainLoop(), and parse_slash_copy().

2174 {
2175  const char *val;
2176 
2177  if (!pset.db)
2178  return false;
2179 
2180  val = PQparameterStatus(pset.db, "standard_conforming_strings");
2181 
2182  if (val && strcmp(val, "on") == 0)
2183  return true;
2184 
2185  return false;
2186 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:31
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6637
long val
Definition: informix.c:664

◆ StoreQueryTuple()

static bool StoreQueryTuple ( const PGresult result)
static

Definition at line 758 of file common.c.

References free, _psqlSettings::gset_prefix, i, pg_log_error, PQfname(), PQgetisnull(), PQgetvalue(), PQnfields(), PQntuples(), pset, psprintf(), SetVariable(), success, value, and _psqlSettings::vars.

Referenced by ExecQueryUsingCursor(), and PrintQueryResults().

759 {
760  bool success = true;
761 
762  if (PQntuples(result) < 1)
763  {
764  pg_log_error("no rows returned for \\gset");
765  success = false;
766  }
767  else if (PQntuples(result) > 1)
768  {
769  pg_log_error("more than one row returned for \\gset");
770  success = false;
771  }
772  else
773  {
774  int i;
775 
776  for (i = 0; i < PQnfields(result); i++)
777  {
778  char *colname = PQfname(result, i);
779  char *varname;
780  char *value;
781 
782  /* concatenate prefix and column name */
783  varname = psprintf("%s%s", pset.gset_prefix, colname);
784 
785  if (!PQgetisnull(result, 0, i))
786  value = PQgetvalue(result, 0, i);
787  else
788  {
789  /* for NULL value, unset rather than set the variable */
790  value = NULL;
791  }
792 
793  if (!SetVariable(pset.vars, varname, value))
794  {
795  free(varname);
796  success = false;
797  break;
798  }
799 
800  free(varname);
801  }
802  }
803 
804  return success;
805 }
char * gset_prefix
Definition: settings.h:96
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2777
PsqlSettings pset
Definition: startup.c:31
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2855
#define pg_log_error(...)
Definition: logging.h:79
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
static struct @143 value
#define free(a)
Definition: header.h:65
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
int i
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3188
static bool success
Definition: initdb.c:161
VariableSpace vars
Definition: settings.h:118

◆ uri_prefix_length()

static int uri_prefix_length ( const char *  connstr)
static

Definition at line 2276 of file common.c.

References short_uri_designator, and uri_designator.

Referenced by recognized_connection_string().

2277 {
2278  /* The connection URI must start with either of the following designators: */
2279  static const char uri_designator[] = "postgresql://";
2280  static const char short_uri_designator[] = "postgres://";
2281 
2282  if (strncmp(connstr, uri_designator,
2283  sizeof(uri_designator) - 1) == 0)
2284  return sizeof(uri_designator) - 1;
2285 
2286  if (strncmp(connstr, short_uri_designator,
2287  sizeof(short_uri_designator) - 1) == 0)
2288  return sizeof(short_uri_designator) - 1;
2289 
2290  return 0;
2291 }
static const char short_uri_designator[]
Definition: fe-connect.c:382
static const char uri_designator[]
Definition: fe-connect.c:381
static char * connstr
Definition: pg_dumpall.c:61

Variable Documentation

◆ sigint_interrupt_enabled

volatile bool sigint_interrupt_enabled = false

◆ sigint_interrupt_jmp

sigjmp_buf sigint_interrupt_jmp

Definition at line 247 of file common.c.

Referenced by do_watch(), handleCopyIn(), MainLoop(), and psql_cancel_callback().