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:6631
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:3319
void ResetCancelConn(void)
Definition: cancel.c:100
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4133
static bool ConnectionUp(void)
Definition: common.c:277
#define fprintf
Definition: port.h:196
void UnsyncVariables(void)
Definition: command.c:3360
#define EXIT_BADCONN
Definition: settings.h:156
bool cur_cmd_interactive
Definition: settings.h:106
void connection_warnings(bool in_startup)
Definition: command.c:3196
#define _(x)
Definition: elog.c:87
void PQreset(PGconn *conn)
Definition: fe-connect.c:4147
#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 1887 of file common.c.

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

Referenced by SendQuery().

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

◆ 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:6578

◆ DescribeQuery()

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

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

1446 {
1447  PGresult *results;
1448  bool OK;
1450  after;
1451 
1452  *elapsed_msec = 0;
1453 
1454  if (pset.timing)
1455  INSTR_TIME_SET_CURRENT(before);
1456 
1457  /*
1458  * To parse the query but not execute it, we prepare it, using the unnamed
1459  * prepared statement. This is invisible to psql users, since there's no
1460  * way to access the unnamed prepared statement from psql user space. The
1461  * next Parse or Query protocol message would overwrite the statement
1462  * anyway. (So there's no great need to clear it when done, which is a
1463  * good thing because libpq provides no easy way to do that.)
1464  */
1465  results = PQprepare(pset.db, "", query, 0, NULL);
1466  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1467  {
1469  SetResultVariables(results, false);
1470  ClearOrSaveResult(results);
1471  return false;
1472  }
1473  PQclear(results);
1474 
1475  results = PQdescribePrepared(pset.db, "");
1476  OK = AcceptResult(results) &&
1477  (PQresultStatus(results) == PGRES_COMMAND_OK);
1478  if (OK && results)
1479  {
1480  if (PQnfields(results) > 0)
1481  {
1483  int i;
1484 
1485  initPQExpBuffer(&buf);
1486 
1487  printfPQExpBuffer(&buf,
1488  "SELECT name AS \"%s\", pg_catalog.format_type(tp, tpm) AS \"%s\"\n"
1489  "FROM (VALUES ",
1490  gettext_noop("Column"),
1491  gettext_noop("Type"));
1492 
1493  for (i = 0; i < PQnfields(results); i++)
1494  {
1495  const char *name;
1496  char *escname;
1497 
1498  if (i > 0)
1499  appendPQExpBufferStr(&buf, ",");
1500 
1501  name = PQfname(results, i);
1502  escname = PQescapeLiteral(pset.db, name, strlen(name));
1503 
1504  if (escname == NULL)
1505  {
1507  PQclear(results);
1508  termPQExpBuffer(&buf);
1509  return false;
1510  }
1511 
1512  appendPQExpBuffer(&buf, "(%s, '%u'::pg_catalog.oid, %d)",
1513  escname,
1514  PQftype(results, i),
1515  PQfmod(results, i));
1516 
1517  PQfreemem(escname);
1518  }
1519 
1520  appendPQExpBufferStr(&buf, ") s(name, tp, tpm)");
1521  PQclear(results);
1522 
1523  results = PQexec(pset.db, buf.data);
1524  OK = AcceptResult(results);
1525 
1526  if (pset.timing)
1527  {
1528  INSTR_TIME_SET_CURRENT(after);
1529  INSTR_TIME_SUBTRACT(after, before);
1530  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1531  }
1532 
1533  if (OK && results)
1534  OK = PrintQueryResults(results);
1535 
1536  termPQExpBuffer(&buf);
1537  }
1538  else
1540  _("The command has no result, or the result has no columns.\n"));
1541  }
1542 
1543  SetResultVariables(results, OK);
1544  ClearOrSaveResult(results);
1545 
1546  return OK;
1547 }
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1096
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:6631
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:1147
FILE * queryFout
Definition: settings.h:84
#define fprintf
Definition: port.h:196
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:521
int i
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define _(x)
Definition: elog.c:87
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 807 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().

808 {
809  bool success = true;
810  int nrows = PQntuples(result);
811  int ncolumns = PQnfields(result);
812  int r,
813  c;
814 
815  /*
816  * We must turn off gexec_flag to avoid infinite recursion. Note that
817  * this allows ExecQueryUsingCursor to be applied to the individual query
818  * results. SendQuery prevents it from being applied when fetching the
819  * queries-to-execute, because it can't handle recursion either.
820  */
821  pset.gexec_flag = false;
822 
823  for (r = 0; r < nrows; r++)
824  {
825  for (c = 0; c < ncolumns; c++)
826  {
827  if (!PQgetisnull(result, r, c))
828  {
829  const char *query = PQgetvalue(result, r, c);
830 
831  /* Abandon execution if cancel_pressed */
832  if (cancel_pressed)
833  goto loop_exit;
834 
835  /*
836  * ECHO_ALL mode should echo these queries, but SendQuery
837  * assumes that MainLoop did that, so we have to do it here.
838  */
840  {
841  puts(query);
842  fflush(stdout);
843  }
844 
845  if (!SendQuery(query))
846  {
847  /* Error - abandon execution if ON_ERROR_STOP */
848  success = false;
849  if (pset.on_error_stop)
850  goto loop_exit;
851  }
852  }
853  }
854  }
855 
856 loop_exit:
857 
858  /*
859  * Restore state. We know gexec_flag was on, else we'd not be here. (We
860  * also know it'll get turned off at end of command, but that's not ours
861  * to do here.)
862  */
863  pset.gexec_flag = true;
864 
865  /* Return true if all queries were successful */
866  return success;
867 }
PSQL_ECHO echo
Definition: settings.h:133
bool singlestep
Definition: settings.h:128
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:97
bool on_error_stop
Definition: settings.h:125
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:1171
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 1561 of file common.c.

References AcceptResult(), appendPQExpBuffer(), Assert, before(), buf, cancel_pressed, cleanup(), ClearOrSaveResult(), ClosePager(), PQExpBufferData::data, _psqlSettings::db, disable_sigpipe_trap(), printTableOpt::expanded, _psqlSettings::fetch_count, _psqlSettings::g_expanded, _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().

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

◆ expand_tilde()

void expand_tilde ( char **  filename)

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

2211 {
2212  if (!filename || !(*filename))
2213  return;
2214 
2215  /*
2216  * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2217  * for short versions of long file names, though the tilde is usually
2218  * toward the end, not at the beginning.
2219  */
2220 #ifndef WIN32
2221 
2222  /* try tilde expansion */
2223  if (**filename == '~')
2224  {
2225  char *fn;
2226  char oldp,
2227  *p;
2228  struct passwd *pw;
2229  char home[MAXPGPATH];
2230 
2231  fn = *filename;
2232  *home = '\0';
2233 
2234  p = fn + 1;
2235  while (*p != '/' && *p != '\0')
2236  p++;
2237 
2238  oldp = *p;
2239  *p = '\0';
2240 
2241  if (*(fn + 1) == '\0')
2242  get_home_path(home); /* ~ or ~/ only */
2243  else if ((pw = getpwnam(fn + 1)) != NULL)
2244  strlcpy(home, pw->pw_dir, sizeof(home)); /* ~user */
2245 
2246  *p = oldp;
2247  if (strlen(home) != 0)
2248  {
2249  char *newfn;
2250 
2251  newfn = psprintf("%s%s", home, p);
2252  free(fn);
2253  *filename = newfn;
2254  }
2255  }
2256 #endif
2257 }
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 2102 of file common.c.

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

Referenced by SendQuery().

2103 {
2104  int wordlen;
2105 
2106  /*
2107  * First advance over any whitespace, comments and left parentheses.
2108  */
2109  for (;;)
2110  {
2111  query = skip_white_space(query);
2112  if (query[0] == '(')
2113  query++;
2114  else
2115  break;
2116  }
2117 
2118  /*
2119  * Check word length (since "selectx" is not "select").
2120  */
2121  wordlen = 0;
2122  while (isalpha((unsigned char) query[wordlen]))
2123  wordlen += PQmblen(&query[wordlen], pset.encoding);
2124 
2125  if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
2126  return true;
2127 
2128  if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
2129  return true;
2130 
2131  return false;
2132 }
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:1216
static const char * skip_white_space(const char *query)
Definition: common.c:1823

◆ is_superuser()

bool is_superuser ( void  )

Definition at line 2142 of file common.c.

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

2143 {
2144  const char *val;
2145 
2146  if (!pset.db)
2147  return false;
2148 
2149  val = PQparameterStatus(pset.db, "is_superuser");
2150 
2151  if (val && strcmp(val, "on") == 0)
2152  return true;
2153 
2154  return false;
2155 }
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:6596
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:196
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:87
void PQfreemem(void *ptr)
Definition: fe-exec.c:3296

◆ PrintQueryResults()

static bool PrintQueryResults ( PGresult results)
static

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

1097 {
1098  bool success;
1099  const char *cmdstatus;
1100 
1101  if (!results)
1102  return false;
1103 
1104  switch (PQresultStatus(results))
1105  {
1106  case PGRES_TUPLES_OK:
1107  /* store or execute or print the data ... */
1108  if (pset.gset_prefix)
1109  success = StoreQueryTuple(results);
1110  else if (pset.gexec_flag)
1111  success = ExecQueryTuples(results);
1112  else if (pset.crosstab_flag)
1113  success = PrintResultsInCrosstab(results);
1114  else
1115  success = PrintQueryTuples(results);
1116  /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
1117  cmdstatus = PQcmdStatus(results);
1118  if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
1119  strncmp(cmdstatus, "UPDATE", 6) == 0 ||
1120  strncmp(cmdstatus, "DELETE", 6) == 0)
1121  PrintQueryStatus(results);
1122  break;
1123 
1124  case PGRES_COMMAND_OK:
1125  PrintQueryStatus(results);
1126  success = true;
1127  break;
1128 
1129  case PGRES_EMPTY_QUERY:
1130  success = true;
1131  break;
1132 
1133  case PGRES_COPY_OUT:
1134  case PGRES_COPY_IN:
1135  /* nothing to do here */
1136  success = true;
1137  break;
1138 
1139  case PGRES_BAD_RESPONSE:
1140  case PGRES_NONFATAL_ERROR:
1141  case PGRES_FATAL_ERROR:
1142  success = false;
1143  break;
1144 
1145  default:
1146  success = false;
1147  pg_log_error("unexpected PQresultStatus: %d",
1148  PQresultStatus(results));
1149  break;
1150  }
1151 
1152  fflush(pset.queryFout);
1153 
1154  return success;
1155 }
static void PrintQueryStatus(PGresult *results)
Definition: common.c:1064
char * gset_prefix
Definition: settings.h:95
PsqlSettings pset
Definition: startup.c:31
#define pg_log_error(...)
Definition: logging.h:79
static bool ExecQueryTuples(const PGresult *result)
Definition: common.c:807
static bool PrintQueryTuples(const PGresult *results)
Definition: common.c:708
bool gexec_flag
Definition: settings.h:97
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:750
bool crosstab_flag
Definition: settings.h:98
static bool success
Definition: initdb.c:161

◆ PrintQueryStatus()

static void PrintQueryStatus ( PGresult results)
static

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

1065 {
1066  char buf[16];
1067 
1068  if (!pset.quiet)
1069  {
1070  if (pset.popt.topt.format == PRINT_HTML)
1071  {
1072  fputs("<p>", pset.queryFout);
1074  fputs("</p>\n", pset.queryFout);
1075  }
1076  else
1077  fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
1078  }
1079 
1080  if (pset.logfile)
1081  fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
1082 
1083  snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
1084  SetVariable(pset.vars, "LASTOID", buf);
1085 }
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:196
static char * buf
Definition: pg_test_fsync.c:67
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
FILE * logfile
Definition: settings.h:115
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:1854
#define snprintf
Definition: port.h:192
VariableSpace vars
Definition: settings.h:117

◆ PrintQueryTuples()

static bool PrintQueryTuples ( const PGresult results)
static

Definition at line 708 of file common.c.

References disable_sigpipe_trap(), printTableOpt::expanded, _psqlSettings::g_expanded, _psqlSettings::gfname, _psqlSettings::logfile, openQueryOutputFile(), _psqlSettings::popt, printQuery(), pset, _psqlSettings::queryFout, restore_sigpipe_trap(), and printQueryOpt::topt.

Referenced by PrintQueryResults().

709 {
710  printQueryOpt my_popt = pset.popt;
711 
712  /* one-shot expanded output requested via \gx */
713  if (pset.g_expanded)
714  my_popt.topt.expanded = 1;
715 
716  /* write output to \g argument, if any */
717  if (pset.gfname)
718  {
719  FILE *fout;
720  bool is_pipe;
721 
722  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
723  return false;
724  if (is_pipe)
726 
727  printQuery(results, &my_popt, fout, false, pset.logfile);
728 
729  if (is_pipe)
730  {
731  pclose(fout);
733  }
734  else
735  fclose(fout);
736  }
737  else
738  printQuery(results, &my_popt, pset.queryFout, false, pset.logfile);
739 
740  return true;
741 }
PsqlSettings pset
Definition: startup.c:31
void disable_sigpipe_trap(void)
Definition: print.c:2941
printTableOpt topt
Definition: print.h:169
FILE * queryFout
Definition: settings.h:84
unsigned short int expanded
Definition: print.h:102
bool g_expanded
Definition: settings.h:94
void restore_sigpipe_trap(void)
Definition: print.c:2964
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:115
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3433

◆ 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:198
const char *const days[]
Definition: datetime.c:68
#define _(x)
Definition: elog.c:87

◆ ProcessResult()

static bool ProcessResult ( PGresult **  results)
static

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

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

◆ 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:620
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(), 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:198
#define fprintf
Definition: port.h:196
static bool AcceptResult(const PGresult *result)
Definition: common.c:352
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:134
void SetCancelConn(PGconn *conn)
Definition: cancel.c:70
FILE * logfile
Definition: settings.h:115
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define _(x)
Definition: elog.c:87

◆ 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:196
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:115
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:3433
#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 2295 of file common.c.

References uri_prefix_length().

Referenced by do_connect().

2296 {
2297  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
2298 }
static int uri_prefix_length(const char *connstr)
Definition: common.c:2268
static char * connstr
Definition: pg_dumpall.c:61

◆ SendQuery()

bool SendQuery ( const char *  query)

Definition at line 1171 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::g_expanded, _psqlSettings::gdesc_flag, _psqlSettings::gexec_flag, _psqlSettings::gfname, _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(), 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().

1172 {
1173  PGresult *results;
1174  PGTransactionStatusType transaction_status;
1175  double elapsed_msec = 0;
1176  bool OK = false;
1177  int i;
1178  bool on_error_rollback_savepoint = false;
1179  static bool on_error_rollback_warning = false;
1180 
1181  if (!pset.db)
1182  {
1183  pg_log_error("You are currently not connected to a database.");
1184  goto sendquery_cleanup;
1185  }
1186 
1187  if (pset.singlestep)
1188  {
1189  char buf[3];
1190 
1191  fflush(stderr);
1192  printf(_("***(Single step mode: verify command)*******************************************\n"
1193  "%s\n"
1194  "***(press return to proceed or enter x and return to cancel)********************\n"),
1195  query);
1196  fflush(stdout);
1197  if (fgets(buf, sizeof(buf), stdin) != NULL)
1198  if (buf[0] == 'x')
1199  goto sendquery_cleanup;
1200  if (cancel_pressed)
1201  goto sendquery_cleanup;
1202  }
1203  else if (pset.echo == PSQL_ECHO_QUERIES)
1204  {
1205  puts(query);
1206  fflush(stdout);
1207  }
1208 
1209  if (pset.logfile)
1210  {
1212  _("********* QUERY **********\n"
1213  "%s\n"
1214  "**************************\n\n"), query);
1215  fflush(pset.logfile);
1216  }
1217 
1219 
1220  transaction_status = PQtransactionStatus(pset.db);
1221 
1222  if (transaction_status == PQTRANS_IDLE &&
1223  !pset.autocommit &&
1224  !command_no_begin(query))
1225  {
1226  results = PQexec(pset.db, "BEGIN");
1227  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1228  {
1230  ClearOrSaveResult(results);
1231  ResetCancelConn();
1232  goto sendquery_cleanup;
1233  }
1234  ClearOrSaveResult(results);
1235  transaction_status = PQtransactionStatus(pset.db);
1236  }
1237 
1238  if (transaction_status == PQTRANS_INTRANS &&
1242  {
1243  if (on_error_rollback_warning == false && pset.sversion < 80000)
1244  {
1245  char sverbuf[32];
1246 
1247  pg_log_warning("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.",
1249  sverbuf, sizeof(sverbuf)));
1250  on_error_rollback_warning = true;
1251  }
1252  else
1253  {
1254  results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
1255  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1256  {
1258  ClearOrSaveResult(results);
1259  ResetCancelConn();
1260  goto sendquery_cleanup;
1261  }
1262  ClearOrSaveResult(results);
1263  on_error_rollback_savepoint = true;
1264  }
1265  }
1266 
1267  if (pset.gdesc_flag)
1268  {
1269  /* Describe query's result columns, without executing it */
1270  OK = DescribeQuery(query, &elapsed_msec);
1271  ResetCancelConn();
1272  results = NULL; /* PQclear(NULL) does nothing */
1273  }
1274  else if (pset.fetch_count <= 0 || pset.gexec_flag ||
1276  {
1277  /* Default fetch-it-all-and-print mode */
1279  after;
1280 
1281  if (pset.timing)
1282  INSTR_TIME_SET_CURRENT(before);
1283 
1284  results = PQexec(pset.db, query);
1285 
1286  /* these operations are included in the timing result: */
1287  ResetCancelConn();
1288  OK = ProcessResult(&results);
1289 
1290  if (pset.timing)
1291  {
1292  INSTR_TIME_SET_CURRENT(after);
1293  INSTR_TIME_SUBTRACT(after, before);
1294  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1295  }
1296 
1297  /* but printing results isn't: */
1298  if (OK && results)
1299  OK = PrintQueryResults(results);
1300  }
1301  else
1302  {
1303  /* Fetch-in-segments mode */
1304  OK = ExecQueryUsingCursor(query, &elapsed_msec);
1305  ResetCancelConn();
1306  results = NULL; /* PQclear(NULL) does nothing */
1307  }
1308 
1309  if (!OK && pset.echo == PSQL_ECHO_ERRORS)
1310  pg_log_info("STATEMENT: %s", query);
1311 
1312  /* If we made a temporary savepoint, possibly release/rollback */
1313  if (on_error_rollback_savepoint)
1314  {
1315  const char *svptcmd = NULL;
1316 
1317  transaction_status = PQtransactionStatus(pset.db);
1318 
1319  switch (transaction_status)
1320  {
1321  case PQTRANS_INERROR:
1322  /* We always rollback on an error */
1323  svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
1324  break;
1325 
1326  case PQTRANS_IDLE:
1327  /* If they are no longer in a transaction, then do nothing */
1328  break;
1329 
1330  case PQTRANS_INTRANS:
1331 
1332  /*
1333  * Do nothing if they are messing with savepoints themselves:
1334  * If the user did RELEASE or ROLLBACK, our savepoint is gone.
1335  * If they issued a SAVEPOINT, releasing ours would remove
1336  * theirs.
1337  */
1338  if (results &&
1339  (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
1340  strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
1341  strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
1342  svptcmd = NULL;
1343  else
1344  svptcmd = "RELEASE pg_psql_temporary_savepoint";
1345  break;
1346 
1347  case PQTRANS_ACTIVE:
1348  case PQTRANS_UNKNOWN:
1349  default:
1350  OK = false;
1351  /* PQTRANS_UNKNOWN is expected given a broken connection. */
1352  if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp())
1353  pg_log_error("unexpected transaction status (%d)",
1354  transaction_status);
1355  break;
1356  }
1357 
1358  if (svptcmd)
1359  {
1360  PGresult *svptres;
1361 
1362  svptres = PQexec(pset.db, svptcmd);
1363  if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
1364  {
1366  ClearOrSaveResult(svptres);
1367  OK = false;
1368 
1369  PQclear(results);
1370  ResetCancelConn();
1371  goto sendquery_cleanup;
1372  }
1373  PQclear(svptres);
1374  }
1375  }
1376 
1377  ClearOrSaveResult(results);
1378 
1379  /* Possible microtiming output */
1380  if (pset.timing)
1381  PrintTiming(elapsed_msec);
1382 
1383  /* check for events that may occur during query execution */
1384 
1385  if (pset.encoding != PQclientEncoding(pset.db) &&
1386  PQclientEncoding(pset.db) >= 0)
1387  {
1388  /* track effects of SET CLIENT_ENCODING */
1391  SetVariable(pset.vars, "ENCODING",
1393  }
1394 
1396 
1397  /* perform cleanup that should occur after any attempted query */
1398 
1399 sendquery_cleanup:
1400 
1401  /* reset \g's output-to-filename trigger */
1402  if (pset.gfname)
1403  {
1404  free(pset.gfname);
1405  pset.gfname = NULL;
1406  }
1407 
1408  /* reset \gx's expanded-mode flag */
1409  pset.g_expanded = false;
1410 
1411  /* reset \gset trigger */
1412  if (pset.gset_prefix)
1413  {
1415  pset.gset_prefix = NULL;
1416  }
1417 
1418  /* reset \gdesc trigger */
1419  pset.gdesc_flag = false;
1420 
1421  /* reset \gexec trigger */
1422  pset.gexec_flag = false;
1423 
1424  /* reset \crosstabview trigger */
1425  pset.crosstab_flag = false;
1426  for (i = 0; i < lengthof(pset.ctv_args); i++)
1427  {
1428  pg_free(pset.ctv_args[i]);
1429  pset.ctv_args[i] = NULL;
1430  }
1431 
1432  return OK;
1433 }
PSQL_ECHO echo
Definition: settings.h:133
bool singlestep
Definition: settings.h:128
char * gset_prefix
Definition: settings.h:95
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1096
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6631
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:97
printTableOpt topt
Definition: print.h:169
static void PrintTiming(double elapsed_msec)
Definition: common.c:477
#define printf(...)
Definition: port.h:198
static bool ConnectionUp(void)
Definition: common.c:277
bool autocommit
Definition: settings.h:124
#define lengthof(array)
Definition: c.h:669
#define fprintf
Definition: port.h:196
PSQL_ERROR_ROLLBACK on_error_rollback
Definition: settings.h:135
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6691
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:99
static int before(chr x, chr y)
Definition: regc_locale.c:496
bool cur_cmd_interactive
Definition: settings.h:106
static bool is_select_command(const char *query)
Definition: common.c:2102
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
bool gdesc_flag
Definition: settings.h:96
static char * buf
Definition: pg_test_fsync.c:67
int fetch_count
Definition: settings.h:130
static bool ProcessResult(PGresult **results)
Definition: common.c:891
void SetCancelConn(PGconn *conn)
Definition: cancel.c:70
bool g_expanded
Definition: settings.h:94
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1561
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6586
static bool DescribeQuery(const char *query, double *elapsed_msec)
Definition: common.c:1445
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
char * gfname
Definition: settings.h:93
FILE * logfile
Definition: settings.h:115
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:98
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:1887
#define _(x)
Definition: elog.c:87
#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:117

◆ session_username()

const char* session_username ( void  )

Definition at line 2189 of file common.c.

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

Referenced by get_prompt().

2190 {
2191  const char *val;
2192 
2193  if (!pset.db)
2194  return NULL;
2195 
2196  val = PQparameterStatus(pset.db, "session_authorization");
2197  if (val)
2198  return val;
2199  else
2200  return PQuser(pset.db);
2201 }
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:6596
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6489
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:2977
void restore_sigpipe_trap(void)
Definition: print.c:2964
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:117

◆ skip_white_space()

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

Definition at line 1823 of file common.c.

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

Referenced by command_no_begin(), and is_select_command().

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

◆ standard_strings()

bool standard_strings ( void  )

Definition at line 2165 of file common.c.

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

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

2166 {
2167  const char *val;
2168 
2169  if (!pset.db)
2170  return false;
2171 
2172  val = PQparameterStatus(pset.db, "standard_conforming_strings");
2173 
2174  if (val && strcmp(val, "on") == 0)
2175  return true;
2176 
2177  return false;
2178 }
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:6596
long val
Definition: informix.c:664

◆ StoreQueryTuple()

static bool StoreQueryTuple ( const PGresult result)
static

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

751 {
752  bool success = true;
753 
754  if (PQntuples(result) < 1)
755  {
756  pg_log_error("no rows returned for \\gset");
757  success = false;
758  }
759  else if (PQntuples(result) > 1)
760  {
761  pg_log_error("more than one row returned for \\gset");
762  success = false;
763  }
764  else
765  {
766  int i;
767 
768  for (i = 0; i < PQnfields(result); i++)
769  {
770  char *colname = PQfname(result, i);
771  char *varname;
772  char *value;
773 
774  /* concatenate prefix and column name */
775  varname = psprintf("%s%s", pset.gset_prefix, colname);
776 
777  if (!PQgetisnull(result, 0, i))
778  value = PQgetvalue(result, 0, i);
779  else
780  {
781  /* for NULL value, unset rather than set the variable */
782  value = NULL;
783  }
784 
785  if (!SetVariable(pset.vars, varname, value))
786  {
787  free(varname);
788  success = false;
789  break;
790  }
791 
792  free(varname);
793  }
794  }
795 
796  return success;
797 }
char * gset_prefix
Definition: settings.h:95
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
static struct @145 value
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#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:117

◆ uri_prefix_length()

static int uri_prefix_length ( const char *  connstr)
static

Definition at line 2268 of file common.c.

References short_uri_designator, and uri_designator.

Referenced by recognized_connection_string().

2269 {
2270  /* The connection URI must start with either of the following designators: */
2271  static const char uri_designator[] = "postgresql://";
2272  static const char short_uri_designator[] = "postgres://";
2273 
2274  if (strncmp(connstr, uri_designator,
2275  sizeof(uri_designator) - 1) == 0)
2276  return sizeof(uri_designator) - 1;
2277 
2278  if (strncmp(connstr, short_uri_designator,
2279  sizeof(short_uri_designator) - 1) == 0)
2280  return sizeof(short_uri_designator) - 1;
2281 
2282  return 0;
2283 }
static const char short_uri_designator[]
Definition: fe-connect.c:374
static const char uri_designator[]
Definition: fe-connect.c:373
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().