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

Go to the source code of this file.

Macros

#define write_stderr(str)
 

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 psql_error (const char *fmt,...)
 
void NoticeProcessor (void *arg, const char *message)
 
static void handle_sigint (SIGNAL_ARGS)
 
void setup_cancel_handler (void)
 
static bool ConnectionUp (void)
 
static bool CheckConnection (void)
 
void SetCancelConn (void)
 
void ResetCancelConn (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
 
static PGcancel *volatile cancelConn = NULL
 

Macro Definition Documentation

◆ write_stderr

#define write_stderr (   str)
Value:
do { \
const char *str_ = (str); \
int rc_; \
rc_ = write(fileno(stderr), str_, strlen(str_)); \
(void) rc_; \
} while (0)
#define write(a, b, c)
Definition: win32.h:14

Definition at line 289 of file common.c.

Referenced by handle_sigint(), and setup_cancel_handler().

Function Documentation

◆ AcceptResult()

static bool AcceptResult ( const PGresult result)
static

Definition at line 506 of file common.c.

References CheckConnection(), _psqlSettings::db, 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, PQerrorMessage(), PQresultStatus(), pset, and psql_error().

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

507 {
508  bool OK;
509 
510  if (!result)
511  OK = false;
512  else
513  switch (PQresultStatus(result))
514  {
515  case PGRES_COMMAND_OK:
516  case PGRES_TUPLES_OK:
517  case PGRES_EMPTY_QUERY:
518  case PGRES_COPY_IN:
519  case PGRES_COPY_OUT:
520  /* Fine, do nothing */
521  OK = true;
522  break;
523 
524  case PGRES_BAD_RESPONSE:
526  case PGRES_FATAL_ERROR:
527  OK = false;
528  break;
529 
530  default:
531  OK = false;
532  psql_error("unexpected PQresultStatus: %d\n",
533  PQresultStatus(result));
534  break;
535  }
536 
537  if (!OK)
538  {
539  const char *error = PQerrorMessage(pset.db);
540 
541  if (strlen(error))
542  psql_error("%s", error);
543 
544  CheckConnection();
545  }
546 
547  return OK;
548 }
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6106
PsqlSettings pset
Definition: startup.c:33
static void error(void)
Definition: sql-dyntest.c:147
static bool CheckConnection(void)
Definition: common.c:407
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
void psql_error(const char *fmt,...)
Definition: common.c:221

◆ CheckConnection()

static bool CheckConnection ( void  )
static

Definition at line 407 of file common.c.

References ConnectionUp(), _psqlSettings::cur_cmd_interactive, _psqlSettings::db, EXIT_BADCONN, PQfinish(), PQreset(), pset, psql_error(), ResetCancelConn(), and UnsyncVariables().

Referenced by AcceptResult(), and ProcessResult().

408 {
409  bool OK;
410 
411  OK = ConnectionUp();
412  if (!OK)
413  {
415  {
416  psql_error("connection to server was lost\n");
417  exit(EXIT_BADCONN);
418  }
419 
420  psql_error("The connection to the server was lost. Attempting reset: ");
421  PQreset(pset.db);
422  OK = ConnectionUp();
423  if (!OK)
424  {
425  psql_error("Failed.\n");
426  PQfinish(pset.db);
427  pset.db = NULL;
428  ResetCancelConn();
429  UnsyncVariables();
430  }
431  else
432  psql_error("Succeeded.\n");
433  }
434 
435  return OK;
436 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3629
static bool ConnectionUp(void)
Definition: common.c:389
void UnsyncVariables(void)
Definition: command.c:3251
#define EXIT_BADCONN
Definition: settings.h:155
bool cur_cmd_interactive
Definition: settings.h:106
void psql_error(const char *fmt,...)
Definition: common.c:221
void ResetCancelConn(void)
Definition: common.c:476
void PQreset(PGconn *conn)
Definition: fe-connect.c:3643

◆ ClearOrSaveResult()

static void ClearOrSaveResult ( PGresult result)
static

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

606 {
607  if (result)
608  {
609  switch (PQresultStatus(result))
610  {
612  case PGRES_FATAL_ERROR:
615  pset.last_error_result = result;
616  break;
617 
618  default:
619  PQclear(result);
620  break;
621  }
622  }
623 }
PsqlSettings pset
Definition: startup.c:33
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
PGresult * last_error_result
Definition: settings.h:89
void PQclear(PGresult *res)
Definition: fe-exec.c:671

◆ command_no_begin()

static bool command_no_begin ( const char *  query)
static

Definition at line 1996 of file common.c.

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

Referenced by SendQuery().

1997 {
1998  int wordlen;
1999 
2000  /*
2001  * First we must advance over any whitespace and comments.
2002  */
2003  query = skip_white_space(query);
2004 
2005  /*
2006  * Check word length (since "beginx" is not "begin").
2007  */
2008  wordlen = 0;
2009  while (isalpha((unsigned char) query[wordlen]))
2010  wordlen += PQmblen(&query[wordlen], pset.encoding);
2011 
2012  /*
2013  * Transaction control commands. These should include every keyword that
2014  * gives rise to a TransactionStmt in the backend grammar, except for the
2015  * savepoint-related commands.
2016  *
2017  * (We assume that START must be START TRANSACTION, since there is
2018  * presently no other "START foo" command.)
2019  */
2020  if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
2021  return true;
2022  if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
2023  return true;
2024  if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
2025  return true;
2026  if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
2027  return true;
2028  if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
2029  return true;
2030  if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
2031  return true;
2032  if (wordlen == 7 && pg_strncasecmp(query, "prepare", 7) == 0)
2033  {
2034  /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
2035  query += wordlen;
2036 
2037  query = skip_white_space(query);
2038 
2039  wordlen = 0;
2040  while (isalpha((unsigned char) query[wordlen]))
2041  wordlen += PQmblen(&query[wordlen], pset.encoding);
2042 
2043  if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0)
2044  return true;
2045  return false;
2046  }
2047 
2048  /*
2049  * Commands not allowed within transactions. The statements checked for
2050  * here should be exactly those that call PreventTransactionChain() in the
2051  * backend.
2052  */
2053  if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
2054  return true;
2055  if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
2056  {
2057  /* CLUSTER with any arguments is allowed in transactions */
2058  query += wordlen;
2059 
2060  query = skip_white_space(query);
2061 
2062  if (isalpha((unsigned char) query[0]))
2063  return false; /* has additional words */
2064  return true; /* it's CLUSTER without arguments */
2065  }
2066 
2067  if (wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0)
2068  {
2069  query += wordlen;
2070 
2071  query = skip_white_space(query);
2072 
2073  wordlen = 0;
2074  while (isalpha((unsigned char) query[wordlen]))
2075  wordlen += PQmblen(&query[wordlen], pset.encoding);
2076 
2077  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
2078  return true;
2079  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
2080  return true;
2081 
2082  /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
2083  if (wordlen == 6 && pg_strncasecmp(query, "unique", 6) == 0)
2084  {
2085  query += wordlen;
2086 
2087  query = skip_white_space(query);
2088 
2089  wordlen = 0;
2090  while (isalpha((unsigned char) query[wordlen]))
2091  wordlen += PQmblen(&query[wordlen], pset.encoding);
2092  }
2093 
2094  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
2095  {
2096  query += wordlen;
2097 
2098  query = skip_white_space(query);
2099 
2100  wordlen = 0;
2101  while (isalpha((unsigned char) query[wordlen]))
2102  wordlen += PQmblen(&query[wordlen], pset.encoding);
2103 
2104  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2105  return true;
2106  }
2107 
2108  return false;
2109  }
2110 
2111  if (wordlen == 5 && pg_strncasecmp(query, "alter", 5) == 0)
2112  {
2113  query += wordlen;
2114 
2115  query = skip_white_space(query);
2116 
2117  wordlen = 0;
2118  while (isalpha((unsigned char) query[wordlen]))
2119  wordlen += PQmblen(&query[wordlen], pset.encoding);
2120 
2121  /* ALTER SYSTEM isn't allowed in xacts */
2122  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2123  return true;
2124 
2125  return false;
2126  }
2127 
2128  /*
2129  * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
2130  * aren't really valid commands so we don't care much. The other four
2131  * possible matches are correct.
2132  */
2133  if ((wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
2134  (wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
2135  {
2136  query += wordlen;
2137 
2138  query = skip_white_space(query);
2139 
2140  wordlen = 0;
2141  while (isalpha((unsigned char) query[wordlen]))
2142  wordlen += PQmblen(&query[wordlen], pset.encoding);
2143 
2144  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
2145  return true;
2146  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2147  return true;
2148  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
2149  return true;
2150 
2151  /* DROP INDEX CONCURRENTLY isn't allowed in xacts */
2152  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
2153  {
2154  query += wordlen;
2155 
2156  query = skip_white_space(query);
2157 
2158  wordlen = 0;
2159  while (isalpha((unsigned char) query[wordlen]))
2160  wordlen += PQmblen(&query[wordlen], pset.encoding);
2161 
2162  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2163  return true;
2164 
2165  return false;
2166  }
2167 
2168  return false;
2169  }
2170 
2171  /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */
2172  if (wordlen == 7 && pg_strncasecmp(query, "discard", 7) == 0)
2173  {
2174  query += wordlen;
2175 
2176  query = skip_white_space(query);
2177 
2178  wordlen = 0;
2179  while (isalpha((unsigned char) query[wordlen]))
2180  wordlen += PQmblen(&query[wordlen], pset.encoding);
2181 
2182  if (wordlen == 3 && pg_strncasecmp(query, "all", 3) == 0)
2183  return true;
2184  return false;
2185  }
2186 
2187  return false;
2188 }
PsqlSettings pset
Definition: startup.c:33
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:1180
static const char * skip_white_space(const char *query)
Definition: common.c:1932

◆ ConnectionUp()

static bool ConnectionUp ( void  )
static

Definition at line 389 of file common.c.

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

Referenced by CheckConnection(), and SendQuery().

390 {
391  return PQstatus(pset.db) != CONNECTION_BAD;
392 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6053

◆ DescribeQuery()

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

Definition at line 1554 of file common.c.

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

Referenced by SendQuery().

1555 {
1556  PGresult *results;
1557  bool OK;
1559  after;
1560 
1561  *elapsed_msec = 0;
1562 
1563  if (pset.timing)
1564  INSTR_TIME_SET_CURRENT(before);
1565 
1566  /*
1567  * To parse the query but not execute it, we prepare it, using the unnamed
1568  * prepared statement. This is invisible to psql users, since there's no
1569  * way to access the unnamed prepared statement from psql user space. The
1570  * next Parse or Query protocol message would overwrite the statement
1571  * anyway. (So there's no great need to clear it when done, which is a
1572  * good thing because libpq provides no easy way to do that.)
1573  */
1574  results = PQprepare(pset.db, "", query, 0, NULL);
1575  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1576  {
1577  psql_error("%s", PQerrorMessage(pset.db));
1578  SetResultVariables(results, false);
1579  ClearOrSaveResult(results);
1580  return false;
1581  }
1582  PQclear(results);
1583 
1584  results = PQdescribePrepared(pset.db, "");
1585  OK = AcceptResult(results) &&
1586  (PQresultStatus(results) == PGRES_COMMAND_OK);
1587  if (OK && results)
1588  {
1589  if (PQnfields(results) > 0)
1590  {
1592  int i;
1593 
1594  initPQExpBuffer(&buf);
1595 
1596  printfPQExpBuffer(&buf,
1597  "SELECT name AS \"%s\", pg_catalog.format_type(tp, tpm) AS \"%s\"\n"
1598  "FROM (VALUES ",
1599  gettext_noop("Column"),
1600  gettext_noop("Type"));
1601 
1602  for (i = 0; i < PQnfields(results); i++)
1603  {
1604  const char *name;
1605  char *escname;
1606 
1607  if (i > 0)
1608  appendPQExpBufferStr(&buf, ",");
1609 
1610  name = PQfname(results, i);
1611  escname = PQescapeLiteral(pset.db, name, strlen(name));
1612 
1613  if (escname == NULL)
1614  {
1615  psql_error("%s", PQerrorMessage(pset.db));
1616  PQclear(results);
1617  termPQExpBuffer(&buf);
1618  return false;
1619  }
1620 
1621  appendPQExpBuffer(&buf, "(%s, '%u'::pg_catalog.oid, %d)",
1622  escname,
1623  PQftype(results, i),
1624  PQfmod(results, i));
1625 
1626  PQfreemem(escname);
1627  }
1628 
1629  appendPQExpBufferStr(&buf, ") s(name, tp, tpm)");
1630  PQclear(results);
1631 
1632  results = PQexec(pset.db, buf.data);
1633  OK = AcceptResult(results);
1634 
1635  if (pset.timing)
1636  {
1637  INSTR_TIME_SET_CURRENT(after);
1638  INSTR_TIME_SUBTRACT(after, before);
1639  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1640  }
1641 
1642  if (OK && results)
1643  OK = PrintQueryResults(results);
1644 
1645  termPQExpBuffer(&buf);
1646  }
1647  else
1648  fprintf(pset.queryFout,
1649  _("The command has no result, or the result has no columns.\n"));
1650  }
1651 
1652  SetResultVariables(results, OK);
1653  ClearOrSaveResult(results);
1654 
1655  return OK;
1656 }
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1205
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2732
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
Definition: fe-exec.c:1941
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6106
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
Definition: fe-exec.c:2114
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:605
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2810
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
static void SetResultVariables(PGresult *results, bool success)
Definition: common.c:563
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:199
struct timeval instr_time
Definition: instr_time.h:147
#define gettext_noop(x)
Definition: c.h:981
FILE * queryFout
Definition: settings.h:84
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
static bool AcceptResult(const PGresult *result)
Definition: common.c:506
static int before(chr x, chr y)
Definition: regc_locale.c:496
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:167
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:2962
static char * buf
Definition: pg_test_fsync.c:67
void psql_error(const char *fmt,...)
Definition: common.c:221
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3519
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int PQfmod(const PGresult *res, int field_num)
Definition: fe-exec.c:2984
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:153
const char * name
Definition: encode.c:521
int i
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
#define _(x)
Definition: elog.c:84
void PQfreemem(void *ptr)
Definition: fe-exec.c:3251
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89

◆ ExecQueryTuples()

static bool ExecQueryTuples ( const PGresult result)
static

Definition at line 959 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, and success.

Referenced by PrintQueryResults().

960 {
961  bool success = true;
962  int nrows = PQntuples(result);
963  int ncolumns = PQnfields(result);
964  int r,
965  c;
966 
967  /*
968  * We must turn off gexec_flag to avoid infinite recursion. Note that
969  * this allows ExecQueryUsingCursor to be applied to the individual query
970  * results. SendQuery prevents it from being applied when fetching the
971  * queries-to-execute, because it can't handle recursion either.
972  */
973  pset.gexec_flag = false;
974 
975  for (r = 0; r < nrows; r++)
976  {
977  for (c = 0; c < ncolumns; c++)
978  {
979  if (!PQgetisnull(result, r, c))
980  {
981  const char *query = PQgetvalue(result, r, c);
982 
983  /* Abandon execution if cancel_pressed */
984  if (cancel_pressed)
985  goto loop_exit;
986 
987  /*
988  * ECHO_ALL mode should echo these queries, but SendQuery
989  * assumes that MainLoop did that, so we have to do it here.
990  */
992  {
993  puts(query);
994  fflush(stdout);
995  }
996 
997  if (!SendQuery(query))
998  {
999  /* Error - abandon execution if ON_ERROR_STOP */
1000  success = false;
1001  if (pset.on_error_stop)
1002  goto loop_exit;
1003  }
1004  }
1005  }
1006  }
1007 
1008 loop_exit:
1009 
1010  /*
1011  * Restore state. We know gexec_flag was on, else we'd not be here. (We
1012  * also know it'll get turned off at end of command, but that's not ours
1013  * to do here.)
1014  */
1015  pset.gexec_flag = true;
1016 
1017  /* Return true if all queries were successful */
1018  return success;
1019 }
PSQL_ECHO echo
Definition: settings.h:132
bool singlestep
Definition: settings.h:128
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2732
PsqlSettings pset
Definition: startup.c:33
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3118
bool gexec_flag
Definition: settings.h:97
bool on_error_stop
Definition: settings.h:125
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2724
volatile bool cancel_pressed
Definition: print.c:46
static bool success
Definition: pg_basebackup.c:99
char * c
bool SendQuery(const char *query)
Definition: common.c:1280
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3143

◆ ExecQueryUsingCursor()

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

Definition at line 1670 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, printTableOpt::stop_table, StoreQueryTuple(), termPQExpBuffer(), _psqlSettings::timing, printQueryOpt::topt, and _psqlSettings::vars.

Referenced by SendQuery().

1671 {
1672  bool OK = true;
1673  PGresult *results;
1675  printQueryOpt my_popt = pset.popt;
1676  FILE *fout;
1677  bool is_pipe;
1678  bool is_pager = false;
1679  bool started_txn = false;
1680  int64 total_tuples = 0;
1681  int ntuples;
1682  int fetch_count;
1683  char fetch_cmd[64];
1685  after;
1686  int flush_error;
1687 
1688  *elapsed_msec = 0;
1689 
1690  /* initialize print options for partial table output */
1691  my_popt.topt.start_table = true;
1692  my_popt.topt.stop_table = false;
1693  my_popt.topt.prior_records = 0;
1694 
1695  if (pset.timing)
1696  INSTR_TIME_SET_CURRENT(before);
1697 
1698  /* if we're not in a transaction, start one */
1700  {
1701  results = PQexec(pset.db, "BEGIN");
1702  OK = AcceptResult(results) &&
1703  (PQresultStatus(results) == PGRES_COMMAND_OK);
1704  ClearOrSaveResult(results);
1705  if (!OK)
1706  return false;
1707  started_txn = true;
1708  }
1709 
1710  /* Send DECLARE CURSOR */
1711  initPQExpBuffer(&buf);
1712  appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1713  query);
1714 
1715  results = PQexec(pset.db, buf.data);
1716  OK = AcceptResult(results) &&
1717  (PQresultStatus(results) == PGRES_COMMAND_OK);
1718  if (!OK)
1719  SetResultVariables(results, OK);
1720  ClearOrSaveResult(results);
1721  termPQExpBuffer(&buf);
1722  if (!OK)
1723  goto cleanup;
1724 
1725  if (pset.timing)
1726  {
1727  INSTR_TIME_SET_CURRENT(after);
1728  INSTR_TIME_SUBTRACT(after, before);
1729  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1730  }
1731 
1732  /*
1733  * In \gset mode, we force the fetch count to be 2, so that we will throw
1734  * the appropriate error if the query returns more than one row.
1735  */
1736  if (pset.gset_prefix)
1737  fetch_count = 2;
1738  else
1739  fetch_count = pset.fetch_count;
1740 
1741  snprintf(fetch_cmd, sizeof(fetch_cmd),
1742  "FETCH FORWARD %d FROM _psql_cursor",
1743  fetch_count);
1744 
1745  /* one-shot expanded output requested via \gx */
1746  if (pset.g_expanded)
1747  my_popt.topt.expanded = 1;
1748 
1749  /* prepare to write output to \g argument, if any */
1750  if (pset.gfname)
1751  {
1752  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
1753  {
1754  OK = false;
1755  goto cleanup;
1756  }
1757  if (is_pipe)
1759  }
1760  else
1761  {
1762  fout = pset.queryFout;
1763  is_pipe = false; /* doesn't matter */
1764  }
1765 
1766  /* clear any pre-existing error indication on the output stream */
1767  clearerr(fout);
1768 
1769  for (;;)
1770  {
1771  if (pset.timing)
1772  INSTR_TIME_SET_CURRENT(before);
1773 
1774  /* get fetch_count tuples at a time */
1775  results = PQexec(pset.db, fetch_cmd);
1776 
1777  if (pset.timing)
1778  {
1779  INSTR_TIME_SET_CURRENT(after);
1780  INSTR_TIME_SUBTRACT(after, before);
1781  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1782  }
1783 
1784  if (PQresultStatus(results) != PGRES_TUPLES_OK)
1785  {
1786  /* shut down pager before printing error message */
1787  if (is_pager)
1788  {
1789  ClosePager(fout);
1790  is_pager = false;
1791  }
1792 
1793  OK = AcceptResult(results);
1794  Assert(!OK);
1795  SetResultVariables(results, OK);
1796  ClearOrSaveResult(results);
1797  break;
1798  }
1799 
1800  if (pset.gset_prefix)
1801  {
1802  /* StoreQueryTuple will complain if not exactly one row */
1803  OK = StoreQueryTuple(results);
1804  ClearOrSaveResult(results);
1805  break;
1806  }
1807 
1808  /*
1809  * Note we do not deal with \gdesc, \gexec or \crosstabview modes here
1810  */
1811 
1812  ntuples = PQntuples(results);
1813  total_tuples += ntuples;
1814 
1815  if (ntuples < fetch_count)
1816  {
1817  /* this is the last result set, so allow footer decoration */
1818  my_popt.topt.stop_table = true;
1819  }
1820  else if (fout == stdout && !is_pager)
1821  {
1822  /*
1823  * If query requires multiple result sets, hack to ensure that
1824  * only one pager instance is used for the whole mess
1825  */
1826  fout = PageOutput(INT_MAX, &(my_popt.topt));
1827  is_pager = true;
1828  }
1829 
1830  printQuery(results, &my_popt, fout, is_pager, pset.logfile);
1831 
1832  ClearOrSaveResult(results);
1833 
1834  /* after the first result set, disallow header decoration */
1835  my_popt.topt.start_table = false;
1836  my_popt.topt.prior_records += ntuples;
1837 
1838  /*
1839  * Make sure to flush the output stream, so intermediate results are
1840  * visible to the client immediately. We check the results because if
1841  * the pager dies/exits/etc, there's no sense throwing more data at
1842  * it.
1843  */
1844  flush_error = fflush(fout);
1845 
1846  /*
1847  * Check if we are at the end, if a cancel was pressed, or if there
1848  * were any errors either trying to flush out the results, or more
1849  * generally on the output stream at all. If we hit any errors
1850  * writing things to the stream, we presume $PAGER has disappeared and
1851  * stop bothering to pull down more data.
1852  */
1853  if (ntuples < fetch_count || cancel_pressed || flush_error ||
1854  ferror(fout))
1855  break;
1856  }
1857 
1858  if (pset.gfname)
1859  {
1860  /* close \g argument file/pipe */
1861  if (is_pipe)
1862  {
1863  pclose(fout);
1865  }
1866  else
1867  fclose(fout);
1868  }
1869  else if (is_pager)
1870  {
1871  /* close transient pager */
1872  ClosePager(fout);
1873  }
1874 
1875  if (OK)
1876  {
1877  /*
1878  * We don't have a PGresult here, and even if we did it wouldn't have
1879  * the right row count, so fake SetResultVariables(). In error cases,
1880  * we already set the result variables above.
1881  */
1882  char buf[32];
1883 
1884  SetVariable(pset.vars, "ERROR", "false");
1885  SetVariable(pset.vars, "SQLSTATE", "00000");
1886  snprintf(buf, sizeof(buf), INT64_FORMAT, total_tuples);
1887  SetVariable(pset.vars, "ROW_COUNT", buf);
1888  }
1889 
1890 cleanup:
1891  if (pset.timing)
1892  INSTR_TIME_SET_CURRENT(before);
1893 
1894  /*
1895  * We try to close the cursor on either success or failure, but on failure
1896  * ignore the result (it's probably just a bleat about being in an aborted
1897  * transaction)
1898  */
1899  results = PQexec(pset.db, "CLOSE _psql_cursor");
1900  if (OK)
1901  {
1902  OK = AcceptResult(results) &&
1903  (PQresultStatus(results) == PGRES_COMMAND_OK);
1904  ClearOrSaveResult(results);
1905  }
1906  else
1907  PQclear(results);
1908 
1909  if (started_txn)
1910  {
1911  results = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK");
1912  OK &= AcceptResult(results) &&
1913  (PQresultStatus(results) == PGRES_COMMAND_OK);
1914  ClearOrSaveResult(results);
1915  }
1916 
1917  if (pset.timing)
1918  {
1919  INSTR_TIME_SET_CURRENT(after);
1920  INSTR_TIME_SUBTRACT(after, before);
1921  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1922  }
1923 
1924  return OK;
1925 }
char * gset_prefix
Definition: settings.h:95
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:605
void disable_sigpipe_trap(void)
Definition: print.c:2801
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void ClosePager(FILE *pagerpipe)
Definition: print.c:2902
static void SetResultVariables(PGresult *results, bool success)
Definition: common.c:563
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:199
struct timeval instr_time
Definition: instr_time.h:147
bool start_table
Definition: print.h:108
printTableOpt topt
Definition: print.h:165
FILE * queryFout
Definition: settings.h:84
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2724
unsigned long prior_records
Definition: print.h:111
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
static bool AcceptResult(const PGresult *result)
Definition: common.c:506
volatile bool cancel_pressed
Definition: print.c:46
static int before(chr x, chr y)
Definition: regc_locale.c:496
unsigned short int expanded
Definition: print.h:99
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:2851
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:167
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:67
int fetch_count
Definition: settings.h:129
bool g_expanded
Definition: settings.h:94
void restore_sigpipe_trap(void)
Definition: print.c:2824
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6061
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:873
FILE * logfile
Definition: settings.h:115
void PQclear(PGresult *res)
Definition: fe-exec.c:671
bool stop_table
Definition: print.h:109
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
#define Assert(condition)
Definition: c.h:670
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3287
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:153
#define INT64_FORMAT
Definition: c.h:338
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:902
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
VariableSpace vars
Definition: settings.h:117

◆ expand_tilde()

void expand_tilde ( char **  filename)

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

2304 {
2305  if (!filename || !(*filename))
2306  return;
2307 
2308  /*
2309  * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2310  * for short versions of long file names, though the tilde is usually
2311  * toward the end, not at the beginning.
2312  */
2313 #ifndef WIN32
2314 
2315  /* try tilde expansion */
2316  if (**filename == '~')
2317  {
2318  char *fn;
2319  char oldp,
2320  *p;
2321  struct passwd *pw;
2322  char home[MAXPGPATH];
2323 
2324  fn = *filename;
2325  *home = '\0';
2326 
2327  p = fn + 1;
2328  while (*p != '/' && *p != '\0')
2329  p++;
2330 
2331  oldp = *p;
2332  *p = '\0';
2333 
2334  if (*(fn + 1) == '\0')
2335  get_home_path(home); /* ~ or ~/ only */
2336  else if ((pw = getpwnam(fn + 1)) != NULL)
2337  strlcpy(home, pw->pw_dir, sizeof(home)); /* ~user */
2338 
2339  *p = oldp;
2340  if (strlen(home) != 0)
2341  {
2342  char *newfn;
2343 
2344  newfn = psprintf("%s%s", home, p);
2345  free(fn);
2346  *filename = newfn;
2347  }
2348  }
2349 #endif
2350 
2351  return;
2352 }
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

◆ handle_sigint()

static void handle_sigint ( SIGNAL_ARGS  )
static

Definition at line 301 of file common.c.

References cancel_pressed, PQcancel(), sigint_interrupt_enabled, sigint_interrupt_jmp, and write_stderr.

Referenced by setup_cancel_handler().

302 {
303  int save_errno = errno;
304  char errbuf[256];
305 
306  /* if we are waiting for input, longjmp out of it */
308  {
309  sigint_interrupt_enabled = false;
310  siglongjmp(sigint_interrupt_jmp, 1);
311  }
312 
313  /* else, set cancel flag to stop any long-running loops */
314  cancel_pressed = true;
315 
316  /* and send QueryCancel if we are processing a database query */
317  if (cancelConn != NULL)
318  {
319  if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
320  write_stderr("Cancel request sent\n");
321  else
322  {
323  write_stderr("Could not send cancel request: ");
324  write_stderr(errbuf);
325  }
326  }
327 
328  errno = save_errno; /* just in case the write changed it */
329 }
volatile bool sigint_interrupt_enabled
Definition: common.c:274
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:276
volatile bool cancel_pressed
Definition: print.c:46
#define write_stderr(str)
Definition: common.c:289
static PGcancel *volatile cancelConn
Definition: common.c:278
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
Definition: fe-connect.c:3905

◆ is_select_command()

static bool is_select_command ( const char *  query)
static

Definition at line 2195 of file common.c.

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

Referenced by SendQuery().

2196 {
2197  int wordlen;
2198 
2199  /*
2200  * First advance over any whitespace, comments and left parentheses.
2201  */
2202  for (;;)
2203  {
2204  query = skip_white_space(query);
2205  if (query[0] == '(')
2206  query++;
2207  else
2208  break;
2209  }
2210 
2211  /*
2212  * Check word length (since "selectx" is not "select").
2213  */
2214  wordlen = 0;
2215  while (isalpha((unsigned char) query[wordlen]))
2216  wordlen += PQmblen(&query[wordlen], pset.encoding);
2217 
2218  if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
2219  return true;
2220 
2221  if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
2222  return true;
2223 
2224  return false;
2225 }
PsqlSettings pset
Definition: startup.c:33
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:1180
static const char * skip_white_space(const char *query)
Definition: common.c:1932

◆ is_superuser()

bool is_superuser ( void  )

Definition at line 2235 of file common.c.

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

2236 {
2237  const char *val;
2238 
2239  if (!pset.db)
2240  return false;
2241 
2242  val = PQparameterStatus(pset.db, "is_superuser");
2243 
2244  if (val && strcmp(val, "on") == 0)
2245  return true;
2246 
2247  return false;
2248 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6071
long val
Definition: informix.c:689

◆ NoticeProcessor()

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

Definition at line 242 of file common.c.

References psql_error().

Referenced by do_connect(), and main().

243 {
244  (void) arg; /* not used */
245  psql_error("%s", message);
246 }
void psql_error(const char *fmt,...)
Definition: common.c:221
void * arg

◆ openQueryOutputFile()

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

Definition at line 50 of file common.c.

References psql_error(), and strerror().

Referenced by ExecQueryUsingCursor(), PrintQueryTuples(), 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  psql_error("%s: %s\n", fname, strerror(errno));
71  return false;
72  }
73 
74  return true;
75 }
void psql_error(const char *fmt,...)
Definition: common.c:221
const char * strerror(int errnum)
Definition: strerror.c:19

◆ PrintNotifications()

static void PrintNotifications ( void  )
static

Definition at line 835 of file common.c.

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

Referenced by SendQuery().

836 {
837  PGnotify *notify;
838 
839  while ((notify = PQnotifies(pset.db)))
840  {
841  /* for backward compatibility, only show payload if nonempty */
842  if (notify->extra[0])
843  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
844  notify->relname, notify->extra, notify->be_pid);
845  else
846  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
847  notify->relname, notify->be_pid);
848  fflush(pset.queryFout);
849  PQfreemem(notify);
850  }
851 }
char * extra
Definition: libpq-fe.h:165
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
PGnotify * PQnotifies(PGconn *conn)
Definition: fe-exec.c:2244
FILE * queryFout
Definition: settings.h:84
int be_pid
Definition: libpq-fe.h:164
char * relname
Definition: libpq-fe.h:163
#define _(x)
Definition: elog.c:84
void PQfreemem(void *ptr)
Definition: fe-exec.c:3251

◆ PrintQueryResults()

static bool PrintQueryResults ( PGresult results)
static

Definition at line 1205 of file common.c.

References _psqlSettings::crosstab_flag, ExecQueryTuples(), _psqlSettings::gexec_flag, _psqlSettings::gset_prefix, 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, psql_error(), _psqlSettings::queryFout, StoreQueryTuple(), and success.

Referenced by DescribeQuery(), and SendQuery().

1206 {
1207  bool success;
1208  const char *cmdstatus;
1209 
1210  if (!results)
1211  return false;
1212 
1213  switch (PQresultStatus(results))
1214  {
1215  case PGRES_TUPLES_OK:
1216  /* store or execute or print the data ... */
1217  if (pset.gset_prefix)
1218  success = StoreQueryTuple(results);
1219  else if (pset.gexec_flag)
1220  success = ExecQueryTuples(results);
1221  else if (pset.crosstab_flag)
1222  success = PrintResultsInCrosstab(results);
1223  else
1224  success = PrintQueryTuples(results);
1225  /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
1226  cmdstatus = PQcmdStatus(results);
1227  if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
1228  strncmp(cmdstatus, "UPDATE", 6) == 0 ||
1229  strncmp(cmdstatus, "DELETE", 6) == 0)
1230  PrintQueryStatus(results);
1231  break;
1232 
1233  case PGRES_COMMAND_OK:
1234  PrintQueryStatus(results);
1235  success = true;
1236  break;
1237 
1238  case PGRES_EMPTY_QUERY:
1239  success = true;
1240  break;
1241 
1242  case PGRES_COPY_OUT:
1243  case PGRES_COPY_IN:
1244  /* nothing to do here */
1245  success = true;
1246  break;
1247 
1248  case PGRES_BAD_RESPONSE:
1249  case PGRES_NONFATAL_ERROR:
1250  case PGRES_FATAL_ERROR:
1251  success = false;
1252  break;
1253 
1254  default:
1255  success = false;
1256  psql_error("unexpected PQresultStatus: %d\n",
1257  PQresultStatus(results));
1258  break;
1259  }
1260 
1261  fflush(pset.queryFout);
1262 
1263  return success;
1264 }
static void PrintQueryStatus(PGresult *results)
Definition: common.c:1173
char * gset_prefix
Definition: settings.h:95
PsqlSettings pset
Definition: startup.c:33
static bool ExecQueryTuples(const PGresult *result)
Definition: common.c:959
static bool PrintQueryTuples(const PGresult *results)
Definition: common.c:860
bool gexec_flag
Definition: settings.h:97
FILE * queryFout
Definition: settings.h:84
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
static bool success
Definition: pg_basebackup.c:99
bool PrintResultsInCrosstab(const PGresult *res)
Definition: crosstabview.c:103
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2995
void psql_error(const char *fmt,...)
Definition: common.c:221
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:902
bool crosstab_flag
Definition: settings.h:98

◆ PrintQueryStatus()

static void PrintQueryStatus ( PGresult results)
static

Definition at line 1173 of file common.c.

References buf, printTableOpt::format, 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().

1174 {
1175  char buf[16];
1176 
1177  if (!pset.quiet)
1178  {
1179  if (pset.popt.topt.format == PRINT_HTML)
1180  {
1181  fputs("<p>", pset.queryFout);
1183  fputs("</p>\n", pset.queryFout);
1184  }
1185  else
1186  fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
1187  }
1188 
1189  if (pset.logfile)
1190  fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
1191 
1192  snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
1193  SetVariable(pset.vars, "LASTOID", buf);
1194 }
PsqlSettings pset
Definition: startup.c:33
Oid PQoidValue(const PGresult *res)
Definition: fe-exec.c:3036
enum printFormat format
Definition: print.h:98
printTableOpt topt
Definition: print.h:165
FILE * queryFout
Definition: settings.h:84
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static char * buf
Definition: pg_test_fsync.c:67
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2995
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:1745
VariableSpace vars
Definition: settings.h:117

◆ PrintQueryTuples()

static bool PrintQueryTuples ( const PGresult results)
static

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

861 {
862  printQueryOpt my_popt = pset.popt;
863 
864  /* one-shot expanded output requested via \gx */
865  if (pset.g_expanded)
866  my_popt.topt.expanded = 1;
867 
868  /* write output to \g argument, if any */
869  if (pset.gfname)
870  {
871  FILE *fout;
872  bool is_pipe;
873 
874  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
875  return false;
876  if (is_pipe)
878 
879  printQuery(results, &my_popt, fout, false, pset.logfile);
880 
881  if (is_pipe)
882  {
883  pclose(fout);
885  }
886  else
887  fclose(fout);
888  }
889  else
890  printQuery(results, &my_popt, pset.queryFout, false, pset.logfile);
891 
892  return true;
893 }
PsqlSettings pset
Definition: startup.c:33
void disable_sigpipe_trap(void)
Definition: print.c:2801
printTableOpt topt
Definition: print.h:165
FILE * queryFout
Definition: settings.h:84
unsigned short int expanded
Definition: print.h:99
bool g_expanded
Definition: settings.h:94
void restore_sigpipe_trap(void)
Definition: print.c:2824
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:3287

◆ PrintTiming()

static void PrintTiming ( double  elapsed_msec)
static

Definition at line 631 of file common.c.

References _, and days.

Referenced by PSQLexecWatch(), and SendQuery().

632 {
633  double seconds;
634  double minutes;
635  double hours;
636  double days;
637 
638  if (elapsed_msec < 1000.0)
639  {
640  /* This is the traditional (pre-v10) output format */
641  printf(_("Time: %.3f ms\n"), elapsed_msec);
642  return;
643  }
644 
645  /*
646  * Note: we could print just seconds, in a format like %06.3f, when the
647  * total is less than 1min. But that's hard to interpret unless we tack
648  * on "s" or otherwise annotate it. Forcing the display to include
649  * minutes seems like a better solution.
650  */
651  seconds = elapsed_msec / 1000.0;
652  minutes = floor(seconds / 60.0);
653  seconds -= 60.0 * minutes;
654  if (minutes < 60.0)
655  {
656  printf(_("Time: %.3f ms (%02d:%06.3f)\n"),
657  elapsed_msec, (int) minutes, seconds);
658  return;
659  }
660 
661  hours = floor(minutes / 60.0);
662  minutes -= 60.0 * hours;
663  if (hours < 24.0)
664  {
665  printf(_("Time: %.3f ms (%02d:%02d:%06.3f)\n"),
666  elapsed_msec, (int) hours, (int) minutes, seconds);
667  return;
668  }
669 
670  days = floor(hours / 24.0);
671  hours -= 24.0 * days;
672  printf(_("Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n"),
673  elapsed_msec, days, (int) hours, (int) minutes, seconds);
674 }
const char *const days[]
Definition: datetime.c:69
#define _(x)
Definition: elog.c:84

◆ ProcessResult()

static bool ProcessResult ( PGresult **  results)
static

Definition at line 1043 of file common.c.

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

Referenced by SendQuery().

1044 {
1045  bool success = true;
1046  bool first_cycle = true;
1047 
1048  for (;;)
1049  {
1050  ExecStatusType result_status;
1051  bool is_copy;
1052  PGresult *next_result;
1053 
1054  if (!AcceptResult(*results))
1055  {
1056  /*
1057  * Failure at this point is always a server-side failure or a
1058  * failure to submit the command string. Either way, we're
1059  * finished with this command string.
1060  */
1061  success = false;
1062  break;
1063  }
1064 
1065  result_status = PQresultStatus(*results);
1066  switch (result_status)
1067  {
1068  case PGRES_EMPTY_QUERY:
1069  case PGRES_COMMAND_OK:
1070  case PGRES_TUPLES_OK:
1071  is_copy = false;
1072  break;
1073 
1074  case PGRES_COPY_OUT:
1075  case PGRES_COPY_IN:
1076  is_copy = true;
1077  break;
1078 
1079  default:
1080  /* AcceptResult() should have caught anything else. */
1081  is_copy = false;
1082  psql_error("unexpected PQresultStatus: %d\n", result_status);
1083  break;
1084  }
1085 
1086  if (is_copy)
1087  {
1088  /*
1089  * Marshal the COPY data. Either subroutine will get the
1090  * connection out of its COPY state, then call PQresultStatus()
1091  * once and report any error.
1092  *
1093  * If pset.copyStream is set, use that as data source/sink,
1094  * otherwise use queryFout or cur_cmd_source as appropriate.
1095  */
1096  FILE *copystream = pset.copyStream;
1097  PGresult *copy_result;
1098 
1099  SetCancelConn();
1100  if (result_status == PGRES_COPY_OUT)
1101  {
1102  if (!copystream)
1103  copystream = pset.queryFout;
1104  success = handleCopyOut(pset.db,
1105  copystream,
1106  &copy_result) && success;
1107 
1108  /*
1109  * Suppress status printing if the report would go to the same
1110  * place as the COPY data just went. Note this doesn't
1111  * prevent error reporting, since handleCopyOut did that.
1112  */
1113  if (copystream == pset.queryFout)
1114  {
1115  PQclear(copy_result);
1116  copy_result = NULL;
1117  }
1118  }
1119  else
1120  {
1121  if (!copystream)
1122  copystream = pset.cur_cmd_source;
1123  success = handleCopyIn(pset.db,
1124  copystream,
1125  PQbinaryTuples(*results),
1126  &copy_result) && success;
1127  }
1128  ResetCancelConn();
1129 
1130  /*
1131  * Replace the PGRES_COPY_OUT/IN result with COPY command's exit
1132  * status, or with NULL if we want to suppress printing anything.
1133  */
1134  PQclear(*results);
1135  *results = copy_result;
1136  }
1137  else if (first_cycle)
1138  {
1139  /* fast path: no COPY commands; PQexec visited all results */
1140  break;
1141  }
1142 
1143  /*
1144  * Check PQgetResult() again. In the typical case of a single-command
1145  * string, it will return NULL. Otherwise, we'll have other results
1146  * to process that may include other COPYs. We keep the last result.
1147  */
1148  next_result = PQgetResult(pset.db);
1149  if (!next_result)
1150  break;
1151 
1152  PQclear(*results);
1153  *results = next_result;
1154  first_cycle = false;
1155  }
1156 
1157  SetResultVariables(*results, success);
1158 
1159  /* may need this to recover from conn loss during COPY */
1160  if (!first_cycle && !CheckConnection())
1161  return false;
1162 
1163  return success;
1164 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
static void SetResultVariables(PGresult *results, bool success)
Definition: common.c:563
FILE * queryFout
Definition: settings.h:84
static bool CheckConnection(void)
Definition: common.c:407
ExecStatusType
Definition: libpq-fe.h:82
int PQbinaryTuples(const PGresult *res)
Definition: fe-exec.c:2740
FILE * copyStream
Definition: settings.h:87
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
FILE * cur_cmd_source
Definition: settings.h:104
static bool AcceptResult(const PGresult *result)
Definition: common.c:506
static bool success
Definition: pg_basebackup.c:99
bool handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res)
Definition: copy.c:435
void SetCancelConn(void)
Definition: common.c:446
void psql_error(const char *fmt,...)
Definition: common.c:221
void PQclear(PGresult *res)
Definition: fe-exec.c:671
bool handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
Definition: copy.c:514
void ResetCancelConn(void)
Definition: common.c:476
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1753

◆ psql_error()

void psql_error ( const char *  fmt,
  ... 
)

Definition at line 221 of file common.c.

References _, _psqlSettings::inputfile, _psqlSettings::lineno, _psqlSettings::progname, pset, _psqlSettings::queryFout, and UINT64_FORMAT.

Referenced by AcceptResult(), CheckConnection(), describeAccessMethods(), describeFunctions(), describeOneTableDetails(), describePublications(), DescribeQuery(), describeSubscriptions(), describeTableDetails(), describeTablespaces(), do_connect(), do_copy(), do_edit(), do_lo_export(), do_lo_import(), do_lo_unlink(), do_pset(), do_shell(), do_watch(), editFile(), exec_command(), exec_command_cd(), exec_command_conninfo(), exec_command_edit(), exec_command_ef_ev(), exec_command_elif(), exec_command_else(), exec_command_encoding(), exec_command_endif(), exec_command_errverbose(), exec_command_include(), exec_command_lo(), exec_command_password(), exec_command_prompt(), exec_command_setenv(), exec_command_sf_sv(), exec_command_unset(), exec_command_write(), get_create_object_cmd(), gets_fromFile(), handleCopyIn(), handleCopyOut(), HandleSlashCmds(), indexOfColumn(), initializeInput(), listCollations(), listDbRoleSettings(), listDefaultACLs(), listExtensionContents(), listExtensions(), listForeignDataWrappers(), listForeignServers(), listForeignTables(), listPublications(), listTables(), listTSConfigs(), listTSConfigsVerbose(), listTSDictionaries(), listTSParsers(), listTSParsersVerbose(), listTSTemplates(), listUserMappings(), MainLoop(), minimal_error_message(), NoticeProcessor(), openQueryOutputFile(), parse_slash_copy(), ParseVariableBool(), ParseVariableNum(), printCrosstab(), printHistory(), printPsetInfo(), PrintQueryResults(), PrintResultsInCrosstab(), process_file(), ProcessResult(), psql_get_variable(), PSQLexec(), PSQLexecWatch(), PsqlVarEnumError(), SendQuery(), SetVariable(), start_lo_xact(), StoreQueryTuple(), strip_lineno_from_objdesc(), and usage().

222 {
223  va_list ap;
224 
225  fflush(stdout);
226  if (pset.queryFout && pset.queryFout != stdout)
227  fflush(pset.queryFout);
228 
229  if (pset.inputfile)
230  fprintf(stderr, "%s:%s:" UINT64_FORMAT ": ", pset.progname, pset.inputfile, pset.lineno);
231  va_start(ap, fmt);
232  vfprintf(stderr, _(fmt), ap);
233  va_end(ap);
234 }
PsqlSettings pset
Definition: startup.c:33
FILE * queryFout
Definition: settings.h:84
char * inputfile
Definition: settings.h:109
const char * progname
Definition: settings.h:108
uint64 lineno
Definition: settings.h:110
#define _(x)
Definition: elog.c:84
#define UINT64_FORMAT
Definition: c.h:339

◆ 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_strdup(), PQerrorMessage(), PQescapeIdentifier(), PQescapeLiteral(), PQfreemem(), PQUOTE_PLAIN, PQUOTE_SHELL_ARG, PQUOTE_SQL_IDENT, PQUOTE_SQL_LITERAL, pset, psql_error(), 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  psql_error("cannot escape without active connection\n");
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  psql_error("%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  psql_error("shell command argument contains a newline or carriage return: \"%s\"\n",
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:6106
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:104
PsqlSettings pset
Definition: startup.c:33
static void error(void)
Definition: sql-dyntest.c:147
bool appendShellStringNoError(PQExpBuffer buf, const char *str)
Definition: string_utils.c:446
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3525
static struct @121 value
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
void psql_error(const char *fmt,...)
Definition: common.c:221
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3519
#define free(a)
Definition: header.h:65
void PQfreemem(void *ptr)
Definition: fe-exec.c:3251
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
VariableSpace vars
Definition: settings.h:117

◆ PSQLexec()

PGresult* PSQLexec ( const char *  query)

Definition at line 690 of file common.c.

References _, AcceptResult(), ClearOrSaveResult(), _psqlSettings::db, _psqlSettings::echo_hidden, _psqlSettings::logfile, PQexec(), pset, PSQL_ECHO_HIDDEN_NOEXEC, PSQL_ECHO_HIDDEN_OFF, psql_error(), ResetCancelConn(), and SetCancelConn().

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(), listPublications(), listSchemas(), listTables(), listTSConfigs(), listTSConfigsVerbose(), listTSDictionaries(), listTSParsers(), listTSParsersVerbose(), listTSTemplates(), listUserMappings(), main(), objectDescription(), permissionsList(), and start_lo_xact().

691 {
692  PGresult *res;
693 
694  if (!pset.db)
695  {
696  psql_error("You are currently not connected to a database.\n");
697  return NULL;
698  }
699 
701  {
702  printf(_("********* QUERY **********\n"
703  "%s\n"
704  "**************************\n\n"), query);
705  fflush(stdout);
706  if (pset.logfile)
707  {
708  fprintf(pset.logfile,
709  _("********* QUERY **********\n"
710  "%s\n"
711  "**************************\n\n"), query);
712  fflush(pset.logfile);
713  }
714 
716  return NULL;
717  }
718 
719  SetCancelConn();
720 
721  res = PQexec(pset.db, query);
722 
723  ResetCancelConn();
724 
725  if (!AcceptResult(res))
726  {
727  ClearOrSaveResult(res);
728  res = NULL;
729  }
730 
731  return res;
732 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:605
static bool AcceptResult(const PGresult *result)
Definition: common.c:506
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:133
void SetCancelConn(void)
Definition: common.c:446
void psql_error(const char *fmt,...)
Definition: common.c:221
FILE * logfile
Definition: settings.h:115
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
void ResetCancelConn(void)
Definition: common.c:476
#define _(x)
Definition: elog.c:84

◆ PSQLexecWatch()

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

Definition at line 745 of file common.c.

References _, AcceptResult(), before(), cancel_pressed, ClearOrSaveResult(), _psqlSettings::db, INSTR_TIME_GET_MILLISEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SUBTRACT, _psqlSettings::logfile, 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, psql_error(), _psqlSettings::queryFout, ResetCancelConn(), SetCancelConn(), _psqlSettings::timing, and printQueryOpt::title.

Referenced by do_watch().

746 {
747  PGresult *res;
748  double elapsed_msec = 0;
750  instr_time after;
751 
752  if (!pset.db)
753  {
754  psql_error("You are currently not connected to a database.\n");
755  return 0;
756  }
757 
758  SetCancelConn();
759 
760  if (pset.timing)
761  INSTR_TIME_SET_CURRENT(before);
762 
763  res = PQexec(pset.db, query);
764 
765  ResetCancelConn();
766 
767  if (!AcceptResult(res))
768  {
769  ClearOrSaveResult(res);
770  return 0;
771  }
772 
773  if (pset.timing)
774  {
775  INSTR_TIME_SET_CURRENT(after);
776  INSTR_TIME_SUBTRACT(after, before);
777  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
778  }
779 
780  /*
781  * If SIGINT is sent while the query is processing, the interrupt will be
782  * consumed. The user's intention, though, is to cancel the entire watch
783  * process, so detect a sent cancellation request and exit in this case.
784  */
785  if (cancel_pressed)
786  {
787  PQclear(res);
788  return 0;
789  }
790 
791  switch (PQresultStatus(res))
792  {
793  case PGRES_TUPLES_OK:
794  printQuery(res, opt, pset.queryFout, false, pset.logfile);
795  break;
796 
797  case PGRES_COMMAND_OK:
798  fprintf(pset.queryFout, "%s\n%s\n\n", opt->title, PQcmdStatus(res));
799  break;
800 
801  case PGRES_EMPTY_QUERY:
802  psql_error(_("\\watch cannot be used with an empty query\n"));
803  PQclear(res);
804  return -1;
805 
806  case PGRES_COPY_OUT:
807  case PGRES_COPY_IN:
808  case PGRES_COPY_BOTH:
809  psql_error(_("\\watch cannot be used with COPY\n"));
810  PQclear(res);
811  return -1;
812 
813  default:
814  psql_error(_("unexpected result status for \\watch\n"));
815  PQclear(res);
816  return -1;
817  }
818 
819  PQclear(res);
820 
821  fflush(pset.queryFout);
822 
823  /* Possible microtiming output */
824  if (pset.timing)
825  PrintTiming(elapsed_msec);
826 
827  return 1;
828 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:605
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:199
struct timeval instr_time
Definition: instr_time.h:147
static void PrintTiming(double elapsed_msec)
Definition: common.c:631
FILE * queryFout
Definition: settings.h:84
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
static bool AcceptResult(const PGresult *result)
Definition: common.c:506
volatile bool cancel_pressed
Definition: print.c:46
static int before(chr x, chr y)
Definition: regc_locale.c:496
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:167
void SetCancelConn(void)
Definition: common.c:446
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2995
void psql_error(const char *fmt,...)
Definition: common.c:221
FILE * logfile
Definition: settings.h:115
void PQclear(PGresult *res)
Definition: fe-exec.c:671
char * title
Definition: print.h:167
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3287
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:153
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
void ResetCancelConn(void)
Definition: common.c:476
#define _(x)
Definition: elog.c:84

◆ recognized_connection_string()

static bool recognized_connection_string ( const char *  connstr)

Definition at line 2390 of file common.c.

References uri_prefix_length().

Referenced by do_connect().

2391 {
2392  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
2393 }
static int uri_prefix_length(const char *connstr)
Definition: common.c:2363
static char * connstr
Definition: pg_dumpall.c:64

◆ ResetCancelConn()

void ResetCancelConn ( void  )

Definition at line 476 of file common.c.

Referenced by CheckConnection(), do_lo_export(), do_lo_import(), do_lo_unlink(), executeMaintenanceCommand(), GetIdleSlot(), GetQueryResult(), ProcessResult(), PSQLexec(), PSQLexecWatch(), and SendQuery().

477 {
478  PGcancel *oldCancelConn;
479 
480 #ifdef WIN32
481  EnterCriticalSection(&cancelConnLock);
482 #endif
483 
484  oldCancelConn = cancelConn;
485  /* be sure handle_sigint doesn't use pointer while freeing */
486  cancelConn = NULL;
487 
488  if (oldCancelConn != NULL)
489  PQfreeCancel(oldCancelConn);
490 
491 #ifdef WIN32
492  LeaveCriticalSection(&cancelConnLock);
493 #endif
494 }
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:3773
static PGcancel *volatile cancelConn
Definition: common.c:278

◆ SendQuery()

bool SendQuery ( const char *  query)

Definition at line 1280 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(), 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(), PGRES_COMMAND_OK, _psqlSettings::popt, PQclear(), PQclientEncoding(), PQcmdStatus(), PQerrorMessage(), PQexec(), PQresultStatus(), PQTRANS_ACTIVE, PQTRANS_IDLE, PQTRANS_INERROR, PQTRANS_INTRANS, PQTRANS_UNKNOWN, PQtransactionStatus(), PrintNotifications(), PrintQueryResults(), PrintTiming(), ProcessResult(), pset, PSQL_ECHO_ERRORS, PSQL_ECHO_QUERIES, psql_error(), PSQL_ERROR_ROLLBACK_OFF, PSQL_ERROR_ROLLBACK_ON, ResetCancelConn(), SetCancelConn(), SetVariable(), _psqlSettings::singlestep, _psqlSettings::sversion, _psqlSettings::timing, printQueryOpt::topt, and _psqlSettings::vars.

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

1281 {
1282  PGresult *results;
1283  PGTransactionStatusType transaction_status;
1284  double elapsed_msec = 0;
1285  bool OK = false;
1286  int i;
1287  bool on_error_rollback_savepoint = false;
1288  static bool on_error_rollback_warning = false;
1289 
1290  if (!pset.db)
1291  {
1292  psql_error("You are currently not connected to a database.\n");
1293  goto sendquery_cleanup;
1294  }
1295 
1296  if (pset.singlestep)
1297  {
1298  char buf[3];
1299 
1300  fflush(stderr);
1301  printf(_("***(Single step mode: verify command)*******************************************\n"
1302  "%s\n"
1303  "***(press return to proceed or enter x and return to cancel)********************\n"),
1304  query);
1305  fflush(stdout);
1306  if (fgets(buf, sizeof(buf), stdin) != NULL)
1307  if (buf[0] == 'x')
1308  goto sendquery_cleanup;
1309  if (cancel_pressed)
1310  goto sendquery_cleanup;
1311  }
1312  else if (pset.echo == PSQL_ECHO_QUERIES)
1313  {
1314  puts(query);
1315  fflush(stdout);
1316  }
1317 
1318  if (pset.logfile)
1319  {
1320  fprintf(pset.logfile,
1321  _("********* QUERY **********\n"
1322  "%s\n"
1323  "**************************\n\n"), query);
1324  fflush(pset.logfile);
1325  }
1326 
1327  SetCancelConn();
1328 
1329  transaction_status = PQtransactionStatus(pset.db);
1330 
1331  if (transaction_status == PQTRANS_IDLE &&
1332  !pset.autocommit &&
1333  !command_no_begin(query))
1334  {
1335  results = PQexec(pset.db, "BEGIN");
1336  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1337  {
1338  psql_error("%s", PQerrorMessage(pset.db));
1339  ClearOrSaveResult(results);
1340  ResetCancelConn();
1341  goto sendquery_cleanup;
1342  }
1343  ClearOrSaveResult(results);
1344  transaction_status = PQtransactionStatus(pset.db);
1345  }
1346 
1347  if (transaction_status == PQTRANS_INTRANS &&
1351  {
1352  if (on_error_rollback_warning == false && pset.sversion < 80000)
1353  {
1354  char sverbuf[32];
1355 
1356  psql_error("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n",
1358  sverbuf, sizeof(sverbuf)));
1359  on_error_rollback_warning = true;
1360  }
1361  else
1362  {
1363  results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
1364  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1365  {
1366  psql_error("%s", PQerrorMessage(pset.db));
1367  ClearOrSaveResult(results);
1368  ResetCancelConn();
1369  goto sendquery_cleanup;
1370  }
1371  ClearOrSaveResult(results);
1372  on_error_rollback_savepoint = true;
1373  }
1374  }
1375 
1376  if (pset.gdesc_flag)
1377  {
1378  /* Describe query's result columns, without executing it */
1379  OK = DescribeQuery(query, &elapsed_msec);
1380  ResetCancelConn();
1381  results = NULL; /* PQclear(NULL) does nothing */
1382  }
1383  else if (pset.fetch_count <= 0 || pset.gexec_flag ||
1385  {
1386  /* Default fetch-it-all-and-print mode */
1388  after;
1389 
1390  if (pset.timing)
1391  INSTR_TIME_SET_CURRENT(before);
1392 
1393  results = PQexec(pset.db, query);
1394 
1395  /* these operations are included in the timing result: */
1396  ResetCancelConn();
1397  OK = ProcessResult(&results);
1398 
1399  if (pset.timing)
1400  {
1401  INSTR_TIME_SET_CURRENT(after);
1402  INSTR_TIME_SUBTRACT(after, before);
1403  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1404  }
1405 
1406  /* but printing results isn't: */
1407  if (OK && results)
1408  OK = PrintQueryResults(results);
1409  }
1410  else
1411  {
1412  /* Fetch-in-segments mode */
1413  OK = ExecQueryUsingCursor(query, &elapsed_msec);
1414  ResetCancelConn();
1415  results = NULL; /* PQclear(NULL) does nothing */
1416  }
1417 
1418  if (!OK && pset.echo == PSQL_ECHO_ERRORS)
1419  psql_error("STATEMENT: %s\n", query);
1420 
1421  /* If we made a temporary savepoint, possibly release/rollback */
1422  if (on_error_rollback_savepoint)
1423  {
1424  const char *svptcmd = NULL;
1425 
1426  transaction_status = PQtransactionStatus(pset.db);
1427 
1428  switch (transaction_status)
1429  {
1430  case PQTRANS_INERROR:
1431  /* We always rollback on an error */
1432  svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
1433  break;
1434 
1435  case PQTRANS_IDLE:
1436  /* If they are no longer in a transaction, then do nothing */
1437  break;
1438 
1439  case PQTRANS_INTRANS:
1440 
1441  /*
1442  * Do nothing if they are messing with savepoints themselves:
1443  * If the user did RELEASE or ROLLBACK, our savepoint is gone.
1444  * If they issued a SAVEPOINT, releasing ours would remove
1445  * theirs.
1446  */
1447  if (results &&
1448  (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
1449  strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
1450  strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
1451  svptcmd = NULL;
1452  else
1453  svptcmd = "RELEASE pg_psql_temporary_savepoint";
1454  break;
1455 
1456  case PQTRANS_ACTIVE:
1457  case PQTRANS_UNKNOWN:
1458  default:
1459  OK = false;
1460  /* PQTRANS_UNKNOWN is expected given a broken connection. */
1461  if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp())
1462  psql_error("unexpected transaction status (%d)\n",
1463  transaction_status);
1464  break;
1465  }
1466 
1467  if (svptcmd)
1468  {
1469  PGresult *svptres;
1470 
1471  svptres = PQexec(pset.db, svptcmd);
1472  if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
1473  {
1474  psql_error("%s", PQerrorMessage(pset.db));
1475  ClearOrSaveResult(svptres);
1476  OK = false;
1477 
1478  PQclear(results);
1479  ResetCancelConn();
1480  goto sendquery_cleanup;
1481  }
1482  PQclear(svptres);
1483  }
1484  }
1485 
1486  ClearOrSaveResult(results);
1487 
1488  /* Possible microtiming output */
1489  if (pset.timing)
1490  PrintTiming(elapsed_msec);
1491 
1492  /* check for events that may occur during query execution */
1493 
1494  if (pset.encoding != PQclientEncoding(pset.db) &&
1495  PQclientEncoding(pset.db) >= 0)
1496  {
1497  /* track effects of SET CLIENT_ENCODING */
1500  SetVariable(pset.vars, "ENCODING",
1502  }
1503 
1505 
1506  /* perform cleanup that should occur after any attempted query */
1507 
1508 sendquery_cleanup:
1509 
1510  /* reset \g's output-to-filename trigger */
1511  if (pset.gfname)
1512  {
1513  free(pset.gfname);
1514  pset.gfname = NULL;
1515  }
1516 
1517  /* reset \gx's expanded-mode flag */
1518  pset.g_expanded = false;
1519 
1520  /* reset \gset trigger */
1521  if (pset.gset_prefix)
1522  {
1524  pset.gset_prefix = NULL;
1525  }
1526 
1527  /* reset \gdesc trigger */
1528  pset.gdesc_flag = false;
1529 
1530  /* reset \gexec trigger */
1531  pset.gexec_flag = false;
1532 
1533  /* reset \crosstabview trigger */
1534  pset.crosstab_flag = false;
1535  for (i = 0; i < lengthof(pset.ctv_args); i++)
1536  {
1537  pg_free(pset.ctv_args[i]);
1538  pset.ctv_args[i] = NULL;
1539  }
1540 
1541  return OK;
1542 }
PSQL_ECHO echo
Definition: settings.h:132
bool singlestep
Definition: settings.h:128
char * gset_prefix
Definition: settings.h:95
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1205
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6106
int encoding
Definition: print.h:118
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:605
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:199
struct timeval instr_time
Definition: instr_time.h:147
bool gexec_flag
Definition: settings.h:97
printTableOpt topt
Definition: print.h:165
static void PrintTiming(double elapsed_msec)
Definition: common.c:631
static bool ConnectionUp(void)
Definition: common.c:389
bool autocommit
Definition: settings.h:124
#define lengthof(array)
Definition: c.h:600
PSQL_ERROR_ROLLBACK on_error_rollback
Definition: settings.h:134
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6166
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
volatile bool cancel_pressed
Definition: print.c:46
static void PrintNotifications(void)
Definition: common.c:835
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:2195
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:167
bool gdesc_flag
Definition: settings.h:96
static char * buf
Definition: pg_test_fsync.c:67
int fetch_count
Definition: settings.h:129
static bool ProcessResult(PGresult **results)
Definition: common.c:1043
bool g_expanded
Definition: settings.h:94
void SetCancelConn(void)
Definition: common.c:446
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1670
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6061
static bool DescribeQuery(const char *query, double *elapsed_msec)
Definition: common.c:1554
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2995
void psql_error(const char *fmt,...)
Definition: common.c:221
char * gfname
Definition: settings.h:93
FILE * logfile
Definition: settings.h:115
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define free(a)
Definition: header.h:65
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
PGTransactionStatusType
Definition: libpq-fe.h:101
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:153
int i
bool crosstab_flag
Definition: settings.h:98
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
int encoding
Definition: settings.h:83
static bool command_no_begin(const char *query)
Definition: common.c:1996
void ResetCancelConn(void)
Definition: common.c:476
#define _(x)
Definition: elog.c:84
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
VariableSpace vars
Definition: settings.h:117

◆ session_username()

const char* session_username ( void  )

Definition at line 2282 of file common.c.

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

Referenced by get_prompt().

2283 {
2284  const char *val;
2285 
2286  if (!pset.db)
2287  return NULL;
2288 
2289  val = PQparameterStatus(pset.db, "session_authorization");
2290  if (val)
2291  return val;
2292  else
2293  return PQuser(pset.db);
2294 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6071
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:5982
long val
Definition: informix.c:689

◆ SetCancelConn()

void SetCancelConn ( void  )

Definition at line 446 of file common.c.

References cancelConn, _psqlSettings::db, PQfreeCancel(), PQgetCancel(), and pset.

Referenced by do_lo_export(), do_lo_import(), do_lo_unlink(), executeMaintenanceCommand(), GetIdleSlot(), GetQueryResult(), ProcessResult(), PSQLexec(), PSQLexecWatch(), and SendQuery().

447 {
448  PGcancel *oldCancelConn;
449 
450 #ifdef WIN32
451  EnterCriticalSection(&cancelConnLock);
452 #endif
453 
454  /* Free the old one if we have one */
455  oldCancelConn = cancelConn;
456  /* be sure handle_sigint doesn't use pointer while freeing */
457  cancelConn = NULL;
458 
459  if (oldCancelConn != NULL)
460  PQfreeCancel(oldCancelConn);
461 
463 
464 #ifdef WIN32
465  LeaveCriticalSection(&cancelConnLock);
466 #endif
467 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:3773
PGcancel * PQgetCancel(PGconn *conn)
Definition: fe-connect.c:3750
static PGcancel *volatile cancelConn
Definition: common.c:278

◆ setQFout()

bool setQFout ( const char *  fname)

Definition at line 85 of file common.c.

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

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:33
bool queryFoutPipe
Definition: settings.h:85
FILE * queryFout
Definition: settings.h:84
void set_sigpipe_trap_state(bool ignore)
Definition: print.c:2837
void restore_sigpipe_trap(void)
Definition: print.c:2824
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 563 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().

564 {
565  if (success)
566  {
567  const char *ntuples = PQcmdTuples(results);
568 
569  SetVariable(pset.vars, "ERROR", "false");
570  SetVariable(pset.vars, "SQLSTATE", "00000");
571  SetVariable(pset.vars, "ROW_COUNT", *ntuples ? ntuples : "0");
572  }
573  else
574  {
575  const char *code = PQresultErrorField(results, PG_DIAG_SQLSTATE);
576  const char *mesg = PQresultErrorField(results, PG_DIAG_MESSAGE_PRIMARY);
577 
578  SetVariable(pset.vars, "ERROR", "true");
579 
580  /*
581  * If there is no SQLSTATE code, use an empty string. This can happen
582  * for libpq-detected errors (e.g., lost connection, ENOMEM).
583  */
584  if (code == NULL)
585  code = "";
586  SetVariable(pset.vars, "SQLSTATE", code);
587  SetVariable(pset.vars, "ROW_COUNT", "0");
588  SetVariable(pset.vars, "LAST_ERROR_SQLSTATE", code);
589  SetVariable(pset.vars, "LAST_ERROR_MESSAGE", mesg ? mesg : "");
590  }
591 }
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
PsqlSettings pset
Definition: startup.c:33
char * PQcmdTuples(PGresult *res)
Definition: fe-exec.c:3065
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
static bool success
Definition: pg_basebackup.c:99
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2709
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
VariableSpace vars
Definition: settings.h:117

◆ setup_cancel_handler()

void setup_cancel_handler ( void  )

Definition at line 332 of file common.c.

Referenced by setup_cancel_handler().

333 {
334  pqsignal(SIGINT, handle_sigint);
335 }
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
static void handle_sigint(SIGNAL_ARGS)
Definition: common.c:301

◆ skip_white_space()

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

Definition at line 1932 of file common.c.

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

Referenced by command_no_begin(), and is_select_command().

1933 {
1934  int cnestlevel = 0; /* slash-star comment nest level */
1935 
1936  while (*query)
1937  {
1938  int mblen = PQmblen(query, pset.encoding);
1939 
1940  /*
1941  * Note: we assume the encoding is a superset of ASCII, so that for
1942  * example "query[0] == '/'" is meaningful. However, we do NOT assume
1943  * that the second and subsequent bytes of a multibyte character
1944  * couldn't look like ASCII characters; so it is critical to advance
1945  * by mblen, not 1, whenever we haven't exactly identified the
1946  * character we are skipping over.
1947  */
1948  if (isspace((unsigned char) *query))
1949  query += mblen;
1950  else if (query[0] == '/' && query[1] == '*')
1951  {
1952  cnestlevel++;
1953  query += 2;
1954  }
1955  else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
1956  {
1957  cnestlevel--;
1958  query += 2;
1959  }
1960  else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
1961  {
1962  query += 2;
1963 
1964  /*
1965  * We have to skip to end of line since any slash-star inside the
1966  * -- comment does NOT start a slash-star comment.
1967  */
1968  while (*query)
1969  {
1970  if (*query == '\n')
1971  {
1972  query++;
1973  break;
1974  }
1975  query += PQmblen(query, pset.encoding);
1976  }
1977  }
1978  else if (cnestlevel > 0)
1979  query += mblen;
1980  else
1981  break; /* found first token */
1982  }
1983 
1984  return query;
1985 }
PsqlSettings pset
Definition: startup.c:33
int encoding
Definition: settings.h:83
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1180

◆ standard_strings()

bool standard_strings ( void  )

Definition at line 2258 of file common.c.

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

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

2259 {
2260  const char *val;
2261 
2262  if (!pset.db)
2263  return false;
2264 
2265  val = PQparameterStatus(pset.db, "standard_conforming_strings");
2266 
2267  if (val && strcmp(val, "on") == 0)
2268  return true;
2269 
2270  return false;
2271 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6071
long val
Definition: informix.c:689

◆ StoreQueryTuple()

static bool StoreQueryTuple ( const PGresult result)
static

Definition at line 902 of file common.c.

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

Referenced by ExecQueryUsingCursor(), and PrintQueryResults().

903 {
904  bool success = true;
905 
906  if (PQntuples(result) < 1)
907  {
908  psql_error("no rows returned for \\gset\n");
909  success = false;
910  }
911  else if (PQntuples(result) > 1)
912  {
913  psql_error("more than one row returned for \\gset\n");
914  success = false;
915  }
916  else
917  {
918  int i;
919 
920  for (i = 0; i < PQnfields(result); i++)
921  {
922  char *colname = PQfname(result, i);
923  char *varname;
924  char *value;
925 
926  /* concatenate prefix and column name */
927  varname = psprintf("%s%s", pset.gset_prefix, colname);
928 
929  if (!PQgetisnull(result, 0, i))
930  value = PQgetvalue(result, 0, i);
931  else
932  {
933  /* for NULL value, unset rather than set the variable */
934  value = NULL;
935  }
936 
937  if (!SetVariable(pset.vars, varname, value))
938  {
939  free(varname);
940  success = false;
941  break;
942  }
943 
944  free(varname);
945  }
946  }
947 
948  return success;
949 }
char * gset_prefix
Definition: settings.h:95
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2732
PsqlSettings pset
Definition: startup.c:33
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3118
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2810
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2724
static struct @121 value
static bool success
Definition: pg_basebackup.c:99
void psql_error(const char *fmt,...)
Definition: common.c:221
#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:3143
VariableSpace vars
Definition: settings.h:117

◆ uri_prefix_length()

static int uri_prefix_length ( const char *  connstr)
static

Definition at line 2363 of file common.c.

References short_uri_designator, and uri_designator.

Referenced by recognized_connection_string().

2364 {
2365  /* The connection URI must start with either of the following designators: */
2366  static const char uri_designator[] = "postgresql://";
2367  static const char short_uri_designator[] = "postgres://";
2368 
2369  if (strncmp(connstr, uri_designator,
2370  sizeof(uri_designator) - 1) == 0)
2371  return sizeof(uri_designator) - 1;
2372 
2373  if (strncmp(connstr, short_uri_designator,
2374  sizeof(short_uri_designator) - 1) == 0)
2375  return sizeof(short_uri_designator) - 1;
2376 
2377  return 0;
2378 }
static const char short_uri_designator[]
Definition: fe-connect.c:351
static const char uri_designator[]
Definition: fe-connect.c:350
static char * connstr
Definition: pg_dumpall.c:64

Variable Documentation

◆ cancelConn

PGcancel* volatile cancelConn = NULL
static

Definition at line 278 of file common.c.

Referenced by ResetCancelConn(), and SetCancelConn().

◆ sigint_interrupt_enabled

volatile bool sigint_interrupt_enabled = false

◆ sigint_interrupt_jmp

sigjmp_buf sigint_interrupt_jmp

Definition at line 276 of file common.c.

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