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, FILE *printQueryFout)
 
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 356 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().

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

◆ CheckConnection()

static bool CheckConnection ( void  )
static

Definition at line 295 of file common.c.

References _, connection_warnings(), ConnectionUp(), _psqlSettings::cur_cmd_interactive, _psqlSettings::db, _psqlSettings::dead_conn, 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; but stash away the failed
317  * connection so that we can still refer to its parameters in a
318  * later \connect attempt. Keep the state cleanup here in sync
319  * with do_connect().
320  */
321  if (pset.dead_conn)
323  pset.dead_conn = pset.db;
324  pset.db = NULL;
325  ResetCancelConn();
326  UnsyncVariables();
327  }
328  else
329  {
330  fprintf(stderr, _("Succeeded.\n"));
331 
332  /*
333  * Re-sync, just in case anything changed. Keep this in sync with
334  * do_connect().
335  */
336  SyncVariables();
337  connection_warnings(false); /* Must be after SyncVariables */
338  }
339  }
340 
341  return OK;
342 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:32
void SyncVariables(void)
Definition: command.c:3661
void ResetCancelConn(void)
Definition: cancel.c:100
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
static bool ConnectionUp(void)
Definition: common.c:277
#define fprintf
Definition: port.h:220
void UnsyncVariables(void)
Definition: command.c:3702
#define EXIT_BADCONN
Definition: settings.h:165
bool cur_cmd_interactive
Definition: settings.h:107
PGconn * dead_conn
Definition: settings.h:125
void connection_warnings(bool in_startup)
Definition: command.c:3538
#define _(x)
Definition: elog.c:89
void PQreset(PGconn *conn)
Definition: fe-connect.c:4245
#define pg_log_fatal(...)
Definition: logging.h:76

◆ ClearOrSaveResult()

static void ClearOrSaveResult ( PGresult result)
static

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

456 {
457  if (result)
458  {
459  switch (PQresultStatus(result))
460  {
462  case PGRES_FATAL_ERROR:
465  pset.last_error_result = result;
466  break;
467 
468  default:
469  PQclear(result);
470  break;
471  }
472  }
473 }
PsqlSettings pset
Definition: startup.c:32
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3178
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 1910 of file common.c.

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

Referenced by SendQuery().

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

◆ 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:32
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6691

◆ DescribeQuery()

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

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

1473 {
1474  PGresult *results;
1475  bool OK;
1477  after;
1478 
1479  *elapsed_msec = 0;
1480 
1481  if (pset.timing)
1482  INSTR_TIME_SET_CURRENT(before);
1483 
1484  /*
1485  * To parse the query but not execute it, we prepare it, using the unnamed
1486  * prepared statement. This is invisible to psql users, since there's no
1487  * way to access the unnamed prepared statement from psql user space. The
1488  * next Parse or Query protocol message would overwrite the statement
1489  * anyway. (So there's no great need to clear it when done, which is a
1490  * good thing because libpq provides no easy way to do that.)
1491  */
1492  results = PQprepare(pset.db, "", query, 0, NULL);
1493  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1494  {
1496  SetResultVariables(results, false);
1497  ClearOrSaveResult(results);
1498  return false;
1499  }
1500  PQclear(results);
1501 
1502  results = PQdescribePrepared(pset.db, "");
1503  OK = AcceptResult(results) &&
1504  (PQresultStatus(results) == PGRES_COMMAND_OK);
1505  if (OK && results)
1506  {
1507  if (PQnfields(results) > 0)
1508  {
1510  int i;
1511 
1512  initPQExpBuffer(&buf);
1513 
1514  printfPQExpBuffer(&buf,
1515  "SELECT name AS \"%s\", pg_catalog.format_type(tp, tpm) AS \"%s\"\n"
1516  "FROM (VALUES ",
1517  gettext_noop("Column"),
1518  gettext_noop("Type"));
1519 
1520  for (i = 0; i < PQnfields(results); i++)
1521  {
1522  const char *name;
1523  char *escname;
1524 
1525  if (i > 0)
1526  appendPQExpBufferStr(&buf, ",");
1527 
1528  name = PQfname(results, i);
1529  escname = PQescapeLiteral(pset.db, name, strlen(name));
1530 
1531  if (escname == NULL)
1532  {
1534  PQclear(results);
1535  termPQExpBuffer(&buf);
1536  return false;
1537  }
1538 
1539  appendPQExpBuffer(&buf, "(%s, '%u'::pg_catalog.oid, %d)",
1540  escname,
1541  PQftype(results, i),
1542  PQfmod(results, i));
1543 
1544  PQfreemem(escname);
1545  }
1546 
1547  appendPQExpBufferStr(&buf, ") s(name, tp, tpm)");
1548  PQclear(results);
1549 
1550  results = PQexec(pset.db, buf.data);
1551  OK = AcceptResult(results);
1552 
1553  if (pset.timing)
1554  {
1555  INSTR_TIME_SET_CURRENT(after);
1556  INSTR_TIME_SUBTRACT(after, before);
1557  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1558  }
1559 
1560  if (OK && results)
1561  OK = PrintQueryResults(results);
1562 
1563  termPQExpBuffer(&buf);
1564  }
1565  else
1567  _("The command has no result, or the result has no columns.\n"));
1568  }
1569 
1570  SetResultVariables(results, OK);
1571  ClearOrSaveResult(results);
1572 
1573  return OK;
1574 }
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1118
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3256
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
Definition: fe-exec.c:2237
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
Definition: fe-exec.c:2386
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
PsqlSettings pset
Definition: startup.c:32
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:455
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3334
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:413
#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:1197
FILE * queryFout
Definition: settings.h:84
#define fprintf
Definition: port.h:220
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3178
static bool AcceptResult(const PGresult *result)
Definition: common.c:356
static int before(chr x, chr y)
Definition: regc_locale.c:492
#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:3486
static char * buf
Definition: pg_test_fsync.c:68
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:4069
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int PQfmod(const PGresult *res, int field_num)
Definition: fe-exec.c:3508
#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:2193
#define _(x)
Definition: elog.c:89
void PQfreemem(void *ptr)
Definition: fe-exec.c:3796
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
#define pg_log_info(...)
Definition: logging.h:88

◆ ExecQueryTuples()

static bool ExecQueryTuples ( const PGresult result)
static

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

830 {
831  bool success = true;
832  int nrows = PQntuples(result);
833  int ncolumns = PQnfields(result);
834  int r,
835  c;
836 
837  /*
838  * We must turn off gexec_flag to avoid infinite recursion. Note that
839  * this allows ExecQueryUsingCursor to be applied to the individual query
840  * results. SendQuery prevents it from being applied when fetching the
841  * queries-to-execute, because it can't handle recursion either.
842  */
843  pset.gexec_flag = false;
844 
845  for (r = 0; r < nrows; r++)
846  {
847  for (c = 0; c < ncolumns; c++)
848  {
849  if (!PQgetisnull(result, r, c))
850  {
851  const char *query = PQgetvalue(result, r, c);
852 
853  /* Abandon execution if cancel_pressed */
854  if (cancel_pressed)
855  goto loop_exit;
856 
857  /*
858  * ECHO_ALL mode should echo these queries, but SendQuery
859  * assumes that MainLoop did that, so we have to do it here.
860  */
862  {
863  puts(query);
864  fflush(stdout);
865  }
866 
867  if (!SendQuery(query))
868  {
869  /* Error - abandon execution if ON_ERROR_STOP */
870  success = false;
871  if (pset.on_error_stop)
872  goto loop_exit;
873  }
874  }
875  }
876  }
877 
878 loop_exit:
879 
880  /*
881  * Restore state. We know gexec_flag was on, else we'd not be here. (We
882  * also know it'll get turned off at end of command, but that's not ours
883  * to do here.)
884  */
885  pset.gexec_flag = true;
886 
887  /* Return true if all queries were successful */
888  return success;
889 }
PSQL_ECHO echo
Definition: settings.h:142
bool singlestep
Definition: settings.h:136
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3256
PsqlSettings pset
Definition: startup.c:32
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3642
bool gexec_flag
Definition: settings.h:98
bool on_error_stop
Definition: settings.h:133
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3248
char * c
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
bool SendQuery(const char *query)
Definition: common.c:1193
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3667
static bool success
Definition: initdb.c:165

◆ ExecQueryUsingCursor()

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

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

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

◆ expand_tilde()

void expand_tilde ( char **  filename)

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

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

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

Referenced by SendQuery().

2126 {
2127  int wordlen;
2128 
2129  /*
2130  * First advance over any whitespace, comments and left parentheses.
2131  */
2132  for (;;)
2133  {
2134  query = skip_white_space(query);
2135  if (query[0] == '(')
2136  query++;
2137  else
2138  break;
2139  }
2140 
2141  /*
2142  * Check word length (since "selectx" is not "select").
2143  */
2144  wordlen = 0;
2145  while (isalpha((unsigned char) query[wordlen]))
2146  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2147 
2148  if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
2149  return true;
2150 
2151  if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
2152  return true;
2153 
2154  return false;
2155 }
PsqlSettings pset
Definition: startup.c:32
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
int PQmblenBounded(const char *s, int encoding)
Definition: fe-misc.c:1202
int encoding
Definition: settings.h:83
static const char * skip_white_space(const char *query)
Definition: common.c:1846

◆ is_superuser()

bool is_superuser ( void  )

Definition at line 2162 of file common.c.

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

2163 {
2164  const char *val;
2165 
2166  if (!pset.db)
2167  return false;
2168 
2169  val = PQparameterStatus(pset.db, "is_superuser");
2170 
2171  if (val && strcmp(val, "on") == 0)
2172  return true;
2173 
2174  return false;
2175 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:32
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6709
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:88

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

◆ PrintNotifications()

static void PrintNotifications ( void  )
static

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

689 {
690  PGnotify *notify;
691 
693  while ((notify = PQnotifies(pset.db)) != NULL)
694  {
695  /* for backward compatibility, only show payload if nonempty */
696  if (notify->extra[0])
697  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
698  notify->relname, notify->extra, notify->be_pid);
699  else
700  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
701  notify->relname, notify->be_pid);
702  fflush(pset.queryFout);
703  PQfreemem(notify);
705  }
706 }
char * extra
Definition: libpq-fe.h:189
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:32
PGnotify * PQnotifies(PGconn *conn)
Definition: fe-exec.c:2516
FILE * queryFout
Definition: settings.h:84
#define fprintf
Definition: port.h:220
int be_pid
Definition: libpq-fe.h:188
char * relname
Definition: libpq-fe.h:187
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1904
#define _(x)
Definition: elog.c:89
void PQfreemem(void *ptr)
Definition: fe-exec.c:3796

◆ PrintQueryResults()

static bool PrintQueryResults ( PGresult results)
static

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

1119 {
1120  bool success;
1121  const char *cmdstatus;
1122 
1123  if (!results)
1124  return false;
1125 
1126  switch (PQresultStatus(results))
1127  {
1128  case PGRES_TUPLES_OK:
1129  /* store or execute or print the data ... */
1130  if (pset.gset_prefix)
1131  success = StoreQueryTuple(results);
1132  else if (pset.gexec_flag)
1133  success = ExecQueryTuples(results);
1134  else if (pset.crosstab_flag)
1135  success = PrintResultsInCrosstab(results);
1136  else
1137  success = PrintQueryTuples(results);
1138  /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
1139  cmdstatus = PQcmdStatus(results);
1140  if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
1141  strncmp(cmdstatus, "UPDATE", 6) == 0 ||
1142  strncmp(cmdstatus, "DELETE", 6) == 0)
1143  PrintQueryStatus(results);
1144  break;
1145 
1146  case PGRES_COMMAND_OK:
1147  PrintQueryStatus(results);
1148  success = true;
1149  break;
1150 
1151  case PGRES_EMPTY_QUERY:
1152  success = true;
1153  break;
1154 
1155  case PGRES_COPY_OUT:
1156  case PGRES_COPY_IN:
1157  /* nothing to do here */
1158  success = true;
1159  break;
1160 
1161  case PGRES_BAD_RESPONSE:
1162  case PGRES_NONFATAL_ERROR:
1163  case PGRES_FATAL_ERROR:
1164  success = false;
1165  break;
1166 
1167  default:
1168  success = false;
1169  pg_log_error("unexpected PQresultStatus: %d",
1170  PQresultStatus(results));
1171  break;
1172  }
1173 
1174  fflush(pset.queryFout);
1175 
1176  return success;
1177 }
static void PrintQueryStatus(PGresult *results)
Definition: common.c:1086
char * gset_prefix
Definition: settings.h:96
PsqlSettings pset
Definition: startup.c:32
#define pg_log_error(...)
Definition: logging.h:80
static bool ExecQueryTuples(const PGresult *result)
Definition: common.c:829
static bool PrintQueryTuples(const PGresult *results)
Definition: common.c:715
bool gexec_flag
Definition: settings.h:98
FILE * queryFout
Definition: settings.h:84
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3178
bool PrintResultsInCrosstab(const PGresult *res)
Definition: crosstabview.c:103
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3519
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:765
bool crosstab_flag
Definition: settings.h:99
static bool success
Definition: initdb.c:165

◆ PrintQueryStatus()

static void PrintQueryStatus ( PGresult results)
static

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

1087 {
1088  char buf[16];
1089 
1090  if (!pset.quiet)
1091  {
1092  if (pset.popt.topt.format == PRINT_HTML)
1093  {
1094  fputs("<p>", pset.queryFout);
1096  fputs("</p>\n", pset.queryFout);
1097  }
1098  else
1099  fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
1100  }
1101 
1102  if (pset.logfile)
1103  fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
1104 
1105  snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
1106  SetVariable(pset.vars, "LASTOID", buf);
1107 }
PsqlSettings pset
Definition: startup.c:32
Oid PQoidValue(const PGresult *res)
Definition: fe-exec.c:3560
enum printFormat format
Definition: print.h:101
printTableOpt topt
Definition: print.h:169
FILE * queryFout
Definition: settings.h:84
#define fprintf
Definition: port.h:220
static char * buf
Definition: pg_test_fsync.c:68
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3519
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:216
VariableSpace vars
Definition: settings.h:118

◆ PrintQueryTuples()

static bool PrintQueryTuples ( const PGresult results)
static

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

716 {
717  bool result = true;
718 
719  /* write output to \g argument, if any */
720  if (pset.gfname)
721  {
722  FILE *fout;
723  bool is_pipe;
724 
725  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
726  return false;
727  if (is_pipe)
729 
730  printQuery(results, &pset.popt, fout, false, pset.logfile);
731  if (ferror(fout))
732  {
733  pg_log_error("could not print result table: %m");
734  result = false;
735  }
736 
737  if (is_pipe)
738  {
739  pclose(fout);
741  }
742  else
743  fclose(fout);
744  }
745  else
746  {
747  printQuery(results, &pset.popt, pset.queryFout, false, pset.logfile);
748  if (ferror(pset.queryFout))
749  {
750  pg_log_error("could not print result table: %m");
751  result = false;
752  }
753  }
754 
755  return result;
756 }
PsqlSettings pset
Definition: startup.c:32
void disable_sigpipe_trap(void)
Definition: print.c:2925
#define pg_log_error(...)
Definition: logging.h:80
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:3420

◆ PrintTiming()

static void PrintTiming ( double  elapsed_msec)
static

Definition at line 481 of file common.c.

References _, days, and printf.

Referenced by PSQLexecWatch(), and SendQuery().

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

◆ ProcessResult()

static bool ProcessResult ( PGresult **  results)
static

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

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

◆ 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:6744
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:128
PsqlSettings pset
Definition: startup.c:32
static void error(void)
Definition: sql-dyntest.c:147
#define pg_log_error(...)
Definition: logging.h:80
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:4075
static char * buf
Definition: pg_test_fsync.c:68
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:4069
static struct @143 value
#define free(a)
Definition: header.h:65
void PQfreemem(void *ptr)
Definition: fe-exec.c:3796
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
#define pg_log_info(...)
Definition: logging.h:88
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:613
static void psql_cancel_callback(void)
Definition: common.c:250

◆ PSQLexec()

PGresult* PSQLexec ( const char *  query)

Definition at line 540 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(), listExtendedStats(), 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().

541 {
542  PGresult *res;
543 
544  if (!pset.db)
545  {
546  pg_log_error("You are currently not connected to a database.");
547  return NULL;
548  }
549 
551  {
552  printf(_("********* QUERY **********\n"
553  "%s\n"
554  "**************************\n\n"), query);
555  fflush(stdout);
556  if (pset.logfile)
557  {
559  _("********* QUERY **********\n"
560  "%s\n"
561  "**************************\n\n"), query);
562  fflush(pset.logfile);
563  }
564 
566  return NULL;
567  }
568 
570 
571  res = PQexec(pset.db, query);
572 
573  ResetCancelConn();
574 
575  if (!AcceptResult(res))
576  {
577  ClearOrSaveResult(res);
578  res = NULL;
579  }
580 
581  return res;
582 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:32
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:455
#define pg_log_error(...)
Definition: logging.h:80
void ResetCancelConn(void)
Definition: cancel.c:100
#define printf(...)
Definition: port.h:222
#define fprintf
Definition: port.h:220
static bool AcceptResult(const PGresult *result)
Definition: common.c:356
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:143
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:2193
#define _(x)
Definition: elog.c:89

◆ PSQLexecWatch()

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

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

596 {
597  PGresult *res;
598  double elapsed_msec = 0;
600  instr_time after;
601  FILE *fout;
602 
603  if (!pset.db)
604  {
605  pg_log_error("You are currently not connected to a database.");
606  return 0;
607  }
608 
610 
611  if (pset.timing)
612  INSTR_TIME_SET_CURRENT(before);
613 
614  res = PQexec(pset.db, query);
615 
616  ResetCancelConn();
617 
618  if (!AcceptResult(res))
619  {
620  ClearOrSaveResult(res);
621  return 0;
622  }
623 
624  if (pset.timing)
625  {
626  INSTR_TIME_SET_CURRENT(after);
627  INSTR_TIME_SUBTRACT(after, before);
628  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
629  }
630 
631  /*
632  * If SIGINT is sent while the query is processing, the interrupt will be
633  * consumed. The user's intention, though, is to cancel the entire watch
634  * process, so detect a sent cancellation request and exit in this case.
635  */
636  if (cancel_pressed)
637  {
638  PQclear(res);
639  return 0;
640  }
641 
642  fout = printQueryFout ? printQueryFout : pset.queryFout;
643 
644  switch (PQresultStatus(res))
645  {
646  case PGRES_TUPLES_OK:
647  printQuery(res, opt, fout, false, pset.logfile);
648  break;
649 
650  case PGRES_COMMAND_OK:
651  fprintf(fout, "%s\n%s\n\n", opt->title, PQcmdStatus(res));
652  break;
653 
654  case PGRES_EMPTY_QUERY:
655  pg_log_error("\\watch cannot be used with an empty query");
656  PQclear(res);
657  return -1;
658 
659  case PGRES_COPY_OUT:
660  case PGRES_COPY_IN:
661  case PGRES_COPY_BOTH:
662  pg_log_error("\\watch cannot be used with COPY");
663  PQclear(res);
664  return -1;
665 
666  default:
667  pg_log_error("unexpected result status for \\watch");
668  PQclear(res);
669  return -1;
670  }
671 
672  PQclear(res);
673 
674  fflush(fout);
675 
676  /* Possible microtiming output */
677  if (pset.timing)
678  PrintTiming(elapsed_msec);
679 
680  return 1;
681 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:32
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:455
#define pg_log_error(...)
Definition: logging.h:80
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:481
FILE * queryFout
Definition: settings.h:84
#define fprintf
Definition: port.h:220
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3178
static bool AcceptResult(const PGresult *result)
Definition: common.c:356
static int before(chr x, chr y)
Definition: regc_locale.c:492
#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:3519
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:3420
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2193

◆ recognized_connection_string()

static bool recognized_connection_string ( const char *  connstr)

Definition at line 2308 of file common.c.

References uri_prefix_length().

Referenced by do_connect().

2309 {
2310  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
2311 }
static int uri_prefix_length(const char *connstr)
Definition: common.c:2281
static char * connstr
Definition: pg_dumpall.c:62

◆ SendQuery()

bool SendQuery ( const char *  query)

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

1194 {
1195  PGresult *results;
1196  PGTransactionStatusType transaction_status;
1197  double elapsed_msec = 0;
1198  bool OK = false;
1199  int i;
1200  bool on_error_rollback_savepoint = false;
1201  static bool on_error_rollback_warning = false;
1202 
1203  if (!pset.db)
1204  {
1205  pg_log_error("You are currently not connected to a database.");
1206  goto sendquery_cleanup;
1207  }
1208 
1209  if (pset.singlestep)
1210  {
1211  char buf[3];
1212 
1213  fflush(stderr);
1214  printf(_("***(Single step mode: verify command)*******************************************\n"
1215  "%s\n"
1216  "***(press return to proceed or enter x and return to cancel)********************\n"),
1217  query);
1218  fflush(stdout);
1219  if (fgets(buf, sizeof(buf), stdin) != NULL)
1220  if (buf[0] == 'x')
1221  goto sendquery_cleanup;
1222  if (cancel_pressed)
1223  goto sendquery_cleanup;
1224  }
1225  else if (pset.echo == PSQL_ECHO_QUERIES)
1226  {
1227  puts(query);
1228  fflush(stdout);
1229  }
1230 
1231  if (pset.logfile)
1232  {
1234  _("********* QUERY **********\n"
1235  "%s\n"
1236  "**************************\n\n"), query);
1237  fflush(pset.logfile);
1238  }
1239 
1241 
1242  transaction_status = PQtransactionStatus(pset.db);
1243 
1244  if (transaction_status == PQTRANS_IDLE &&
1245  !pset.autocommit &&
1246  !command_no_begin(query))
1247  {
1248  results = PQexec(pset.db, "BEGIN");
1249  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1250  {
1252  ClearOrSaveResult(results);
1253  ResetCancelConn();
1254  goto sendquery_cleanup;
1255  }
1256  ClearOrSaveResult(results);
1257  transaction_status = PQtransactionStatus(pset.db);
1258  }
1259 
1260  if (transaction_status == PQTRANS_INTRANS &&
1264  {
1265  if (on_error_rollback_warning == false && pset.sversion < 80000)
1266  {
1267  char sverbuf[32];
1268 
1269  pg_log_warning("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.",
1271  sverbuf, sizeof(sverbuf)));
1272  on_error_rollback_warning = true;
1273  }
1274  else
1275  {
1276  results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
1277  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1278  {
1280  ClearOrSaveResult(results);
1281  ResetCancelConn();
1282  goto sendquery_cleanup;
1283  }
1284  ClearOrSaveResult(results);
1285  on_error_rollback_savepoint = true;
1286  }
1287  }
1288 
1289  if (pset.gdesc_flag)
1290  {
1291  /* Describe query's result columns, without executing it */
1292  OK = DescribeQuery(query, &elapsed_msec);
1293  ResetCancelConn();
1294  results = NULL; /* PQclear(NULL) does nothing */
1295  }
1296  else if (pset.fetch_count <= 0 || pset.gexec_flag ||
1298  {
1299  /* Default fetch-it-all-and-print mode */
1301  after;
1302 
1303  if (pset.timing)
1304  INSTR_TIME_SET_CURRENT(before);
1305 
1306  results = PQexec(pset.db, query);
1307 
1308  /* these operations are included in the timing result: */
1309  ResetCancelConn();
1310  OK = ProcessResult(&results);
1311 
1312  if (pset.timing)
1313  {
1314  INSTR_TIME_SET_CURRENT(after);
1315  INSTR_TIME_SUBTRACT(after, before);
1316  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1317  }
1318 
1319  /* but printing results isn't: */
1320  if (OK && results)
1321  OK = PrintQueryResults(results);
1322  }
1323  else
1324  {
1325  /* Fetch-in-segments mode */
1326  OK = ExecQueryUsingCursor(query, &elapsed_msec);
1327  ResetCancelConn();
1328  results = NULL; /* PQclear(NULL) does nothing */
1329  }
1330 
1331  if (!OK && pset.echo == PSQL_ECHO_ERRORS)
1332  pg_log_info("STATEMENT: %s", query);
1333 
1334  /* If we made a temporary savepoint, possibly release/rollback */
1335  if (on_error_rollback_savepoint)
1336  {
1337  const char *svptcmd = NULL;
1338 
1339  transaction_status = PQtransactionStatus(pset.db);
1340 
1341  switch (transaction_status)
1342  {
1343  case PQTRANS_INERROR:
1344  /* We always rollback on an error */
1345  svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
1346  break;
1347 
1348  case PQTRANS_IDLE:
1349  /* If they are no longer in a transaction, then do nothing */
1350  break;
1351 
1352  case PQTRANS_INTRANS:
1353 
1354  /*
1355  * Do nothing if they are messing with savepoints themselves:
1356  * If the user did COMMIT AND CHAIN, RELEASE or ROLLBACK, our
1357  * savepoint is gone. If they issued a SAVEPOINT, releasing
1358  * ours would remove theirs.
1359  */
1360  if (results &&
1361  (strcmp(PQcmdStatus(results), "COMMIT") == 0 ||
1362  strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
1363  strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
1364  strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
1365  svptcmd = NULL;
1366  else
1367  svptcmd = "RELEASE pg_psql_temporary_savepoint";
1368  break;
1369 
1370  case PQTRANS_ACTIVE:
1371  case PQTRANS_UNKNOWN:
1372  default:
1373  OK = false;
1374  /* PQTRANS_UNKNOWN is expected given a broken connection. */
1375  if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp())
1376  pg_log_error("unexpected transaction status (%d)",
1377  transaction_status);
1378  break;
1379  }
1380 
1381  if (svptcmd)
1382  {
1383  PGresult *svptres;
1384 
1385  svptres = PQexec(pset.db, svptcmd);
1386  if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
1387  {
1389  ClearOrSaveResult(svptres);
1390  OK = false;
1391 
1392  PQclear(results);
1393  ResetCancelConn();
1394  goto sendquery_cleanup;
1395  }
1396  PQclear(svptres);
1397  }
1398  }
1399 
1400  ClearOrSaveResult(results);
1401 
1402  /* Possible microtiming output */
1403  if (pset.timing)
1404  PrintTiming(elapsed_msec);
1405 
1406  /* check for events that may occur during query execution */
1407 
1408  if (pset.encoding != PQclientEncoding(pset.db) &&
1409  PQclientEncoding(pset.db) >= 0)
1410  {
1411  /* track effects of SET CLIENT_ENCODING */
1414  SetVariable(pset.vars, "ENCODING",
1416  }
1417 
1419 
1420  /* perform cleanup that should occur after any attempted query */
1421 
1422 sendquery_cleanup:
1423 
1424  /* reset \g's output-to-filename trigger */
1425  if (pset.gfname)
1426  {
1427  free(pset.gfname);
1428  pset.gfname = NULL;
1429  }
1430 
1431  /* restore print settings if \g changed them */
1432  if (pset.gsavepopt)
1433  {
1435  pset.gsavepopt = NULL;
1436  }
1437 
1438  /* reset \gset trigger */
1439  if (pset.gset_prefix)
1440  {
1442  pset.gset_prefix = NULL;
1443  }
1444 
1445  /* reset \gdesc trigger */
1446  pset.gdesc_flag = false;
1447 
1448  /* reset \gexec trigger */
1449  pset.gexec_flag = false;
1450 
1451  /* reset \crosstabview trigger */
1452  pset.crosstab_flag = false;
1453  for (i = 0; i < lengthof(pset.ctv_args); i++)
1454  {
1455  pg_free(pset.ctv_args[i]);
1456  pset.ctv_args[i] = NULL;
1457  }
1458 
1459  return OK;
1460 }
PSQL_ECHO echo
Definition: settings.h:142
bool singlestep
Definition: settings.h:136
char * gset_prefix
Definition: settings.h:96
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1118
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
int encoding
Definition: print.h:122
PsqlSettings pset
Definition: startup.c:32
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:455
#define pg_log_error(...)
Definition: logging.h:80
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:481
printQueryOpt * gsavepopt
Definition: settings.h:94
#define printf(...)
Definition: port.h:222
static bool ConnectionUp(void)
Definition: common.c:277
bool autocommit
Definition: settings.h:132
#define lengthof(array)
Definition: c.h:734
#define fprintf
Definition: port.h:220
PSQL_ERROR_ROLLBACK on_error_rollback
Definition: settings.h:144
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6821
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3178
static void PrintNotifications(void)
Definition: common.c:688
char * ctv_args[4]
Definition: settings.h:100
static int before(chr x, chr y)
Definition: regc_locale.c:492
bool cur_cmd_interactive
Definition: settings.h:107
static bool is_select_command(const char *query)
Definition: common.c:2125
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
Definition: command.c:4700
bool gdesc_flag
Definition: settings.h:97
static char * buf
Definition: pg_test_fsync.c:68
int fetch_count
Definition: settings.h:139
static bool ProcessResult(PGresult **results)
Definition: common.c:913
void SetCancelConn(PGconn *conn)
Definition: cancel.c:70
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1588
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6699
static bool DescribeQuery(const char *query, double *elapsed_msec)
Definition: common.c:1472
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3519
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:114
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:2193
#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:1910
#define _(x)
Definition: elog.c:89
#define pg_log_info(...)
Definition: logging.h:88
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 2202 of file common.c.

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

Referenced by get_prompt().

2203 {
2204  const char *val;
2205 
2206  if (!pset.db)
2207  return NULL;
2208 
2209  val = PQparameterStatus(pset.db, "session_authorization");
2210  if (val)
2211  return val;
2212  else
2213  return PQuser(pset.db);
2214 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:32
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6709
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6598
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:32
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 413 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().

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

◆ skip_white_space()

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

Definition at line 1846 of file common.c.

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

Referenced by command_no_begin(), and is_select_command().

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

◆ standard_strings()

bool standard_strings ( void  )

Definition at line 2182 of file common.c.

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

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

2183 {
2184  const char *val;
2185 
2186  if (!pset.db)
2187  return false;
2188 
2189  val = PQparameterStatus(pset.db, "standard_conforming_strings");
2190 
2191  if (val && strcmp(val, "on") == 0)
2192  return true;
2193 
2194  return false;
2195 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:32
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6709
long val
Definition: informix.c:664

◆ StoreQueryTuple()

static bool StoreQueryTuple ( const PGresult result)
static

Definition at line 765 of file common.c.

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

Referenced by ExecQueryUsingCursor(), and PrintQueryResults().

766 {
767  bool success = true;
768 
769  if (PQntuples(result) < 1)
770  {
771  pg_log_error("no rows returned for \\gset");
772  success = false;
773  }
774  else if (PQntuples(result) > 1)
775  {
776  pg_log_error("more than one row returned for \\gset");
777  success = false;
778  }
779  else
780  {
781  int i;
782 
783  for (i = 0; i < PQnfields(result); i++)
784  {
785  char *colname = PQfname(result, i);
786  char *varname;
787  char *value;
788 
789  /* concatenate prefix and column name */
790  varname = psprintf("%s%s", pset.gset_prefix, colname);
791 
792  if (VariableHasHook(pset.vars, varname))
793  {
794  pg_log_warning("attempt to \\gset into specially treated variable \"%s\" ignored",
795  varname);
796  continue;
797  }
798 
799  if (!PQgetisnull(result, 0, i))
800  value = PQgetvalue(result, 0, i);
801  else
802  {
803  /* for NULL value, unset rather than set the variable */
804  value = NULL;
805  }
806 
807  if (!SetVariable(pset.vars, varname, value))
808  {
809  free(varname);
810  success = false;
811  break;
812  }
813 
814  free(varname);
815  }
816  }
817 
818  return success;
819 }
char * gset_prefix
Definition: settings.h:96
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3256
PsqlSettings pset
Definition: startup.c:32
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3642
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3334
#define pg_log_error(...)
Definition: logging.h:80
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3248
bool VariableHasHook(VariableSpace space, const char *name)
Definition: variables.c:368
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
#define pg_log_warning(...)
Definition: pgfnames.c:24
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3667
static bool success
Definition: initdb.c:165
VariableSpace vars
Definition: settings.h:118

◆ uri_prefix_length()

static int uri_prefix_length ( const char *  connstr)
static

Definition at line 2281 of file common.c.

References short_uri_designator, and uri_designator.

Referenced by recognized_connection_string().

2282 {
2283  /* The connection URI must start with either of the following designators: */
2284  static const char uri_designator[] = "postgresql://";
2285  static const char short_uri_designator[] = "postgres://";
2286 
2287  if (strncmp(connstr, uri_designator,
2288  sizeof(uri_designator) - 1) == 0)
2289  return sizeof(uri_designator) - 1;
2290 
2291  if (strncmp(connstr, short_uri_designator,
2292  sizeof(short_uri_designator) - 1) == 0)
2293  return sizeof(short_uri_designator) - 1;
2294 
2295  return 0;
2296 }
static const char short_uri_designator[]
Definition: fe-connect.c:372
static const char uri_designator[]
Definition: fe-connect.c:371
static char * connstr
Definition: pg_dumpall.c:62

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().