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/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.

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

498 {
499  bool OK;
500 
501  if (!result)
502  OK = false;
503  else
504  switch (PQresultStatus(result))
505  {
506  case PGRES_COMMAND_OK:
507  case PGRES_TUPLES_OK:
508  case PGRES_EMPTY_QUERY:
509  case PGRES_COPY_IN:
510  case PGRES_COPY_OUT:
511  /* Fine, do nothing */
512  OK = true;
513  break;
514 
515  case PGRES_BAD_RESPONSE:
517  case PGRES_FATAL_ERROR:
518  OK = false;
519  break;
520 
521  default:
522  OK = false;
523  pg_log_error("unexpected PQresultStatus: %d",
524  PQresultStatus(result));
525  break;
526  }
527 
528  if (!OK)
529  {
530  const char *error = PQerrorMessage(pset.db);
531 
532  if (strlen(error))
533  pg_log_info("%s", error);
534 
535  CheckConnection();
536  }
537 
538  return OK;
539 }
PGconn * db
Definition: settings.h:83
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
PsqlSettings pset
Definition: startup.c:31
static void error(void)
Definition: sql-dyntest.c:147
#define pg_log_error(...)
Definition: logging.h:79
static bool CheckConnection(void)
Definition: common.c:384
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
#define pg_log_info(...)
Definition: logging.h:87

◆ CheckConnection()

static bool CheckConnection ( void  )
static

Definition at line 384 of file common.c.

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

Referenced by AcceptResult(), and ProcessResult().

385 {
386  bool OK;
387 
388  OK = ConnectionUp();
389  if (!OK)
390  {
392  {
393  pg_log_fatal("connection to server was lost");
394  exit(EXIT_BADCONN);
395  }
396 
397  fprintf(stderr, _("The connection to the server was lost. Attempting reset: "));
398  PQreset(pset.db);
399  OK = ConnectionUp();
400  if (!OK)
401  {
402  fprintf(stderr, _("Failed.\n"));
403 
404  /*
405  * Transition to having no connection. Keep this bit in sync with
406  * do_connect().
407  */
408  PQfinish(pset.db);
409  pset.db = NULL;
410  ResetCancelConn();
411  UnsyncVariables();
412  }
413  else
414  {
415  fprintf(stderr, _("Succeeded.\n"));
416 
417  /*
418  * Re-sync, just in case anything changed. Keep this in sync with
419  * do_connect().
420  */
421  SyncVariables();
422  connection_warnings(false); /* Must be after SyncVariables */
423  }
424  }
425 
426  return OK;
427 }
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
void SyncVariables(void)
Definition: command.c:3320
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
static bool ConnectionUp(void)
Definition: common.c:366
#define fprintf
Definition: port.h:196
void UnsyncVariables(void)
Definition: command.c:3361
#define EXIT_BADCONN
Definition: settings.h:157
bool cur_cmd_interactive
Definition: settings.h:107
void connection_warnings(bool in_startup)
Definition: command.c:3197
void ResetCancelConn(void)
Definition: common.c:467
#define _(x)
Definition: elog.c:87
void PQreset(PGconn *conn)
Definition: fe-connect.c:4133
#define pg_log_fatal(...)
Definition: logging.h:75

◆ ClearOrSaveResult()

static void ClearOrSaveResult ( PGresult result)
static

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

597 {
598  if (result)
599  {
600  switch (PQresultStatus(result))
601  {
603  case PGRES_FATAL_ERROR:
606  pset.last_error_result = result;
607  break;
608 
609  default:
610  PQclear(result);
611  break;
612  }
613  }
614 }
PsqlSettings pset
Definition: startup.c:31
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
PGresult * last_error_result
Definition: settings.h:90
void PQclear(PGresult *res)
Definition: fe-exec.c:694

◆ command_no_begin()

static bool command_no_begin ( const char *  query)
static

Definition at line 2032 of file common.c.

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

Referenced by SendQuery().

2033 {
2034  int wordlen;
2035 
2036  /*
2037  * First we must advance over any whitespace and comments.
2038  */
2039  query = skip_white_space(query);
2040 
2041  /*
2042  * Check word length (since "beginx" is not "begin").
2043  */
2044  wordlen = 0;
2045  while (isalpha((unsigned char) query[wordlen]))
2046  wordlen += PQmblen(&query[wordlen], pset.encoding);
2047 
2048  /*
2049  * Transaction control commands. These should include every keyword that
2050  * gives rise to a TransactionStmt in the backend grammar, except for the
2051  * savepoint-related commands.
2052  *
2053  * (We assume that START must be START TRANSACTION, since there is
2054  * presently no other "START foo" command.)
2055  */
2056  if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
2057  return true;
2058  if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
2059  return true;
2060  if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
2061  return true;
2062  if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
2063  return true;
2064  if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
2065  return true;
2066  if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
2067  return true;
2068  if (wordlen == 7 && pg_strncasecmp(query, "prepare", 7) == 0)
2069  {
2070  /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
2071  query += wordlen;
2072 
2073  query = skip_white_space(query);
2074 
2075  wordlen = 0;
2076  while (isalpha((unsigned char) query[wordlen]))
2077  wordlen += PQmblen(&query[wordlen], pset.encoding);
2078 
2079  if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0)
2080  return true;
2081  return false;
2082  }
2083 
2084  /*
2085  * Commands not allowed within transactions. The statements checked for
2086  * here should be exactly those that call PreventInTransactionBlock() in
2087  * the backend.
2088  */
2089  if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
2090  return true;
2091  if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
2092  {
2093  /* CLUSTER with any arguments is allowed in transactions */
2094  query += wordlen;
2095 
2096  query = skip_white_space(query);
2097 
2098  if (isalpha((unsigned char) query[0]))
2099  return false; /* has additional words */
2100  return true; /* it's CLUSTER without arguments */
2101  }
2102 
2103  if (wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0)
2104  {
2105  query += wordlen;
2106 
2107  query = skip_white_space(query);
2108 
2109  wordlen = 0;
2110  while (isalpha((unsigned char) query[wordlen]))
2111  wordlen += PQmblen(&query[wordlen], pset.encoding);
2112 
2113  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
2114  return true;
2115  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
2116  return true;
2117 
2118  /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
2119  if (wordlen == 6 && pg_strncasecmp(query, "unique", 6) == 0)
2120  {
2121  query += wordlen;
2122 
2123  query = skip_white_space(query);
2124 
2125  wordlen = 0;
2126  while (isalpha((unsigned char) query[wordlen]))
2127  wordlen += PQmblen(&query[wordlen], pset.encoding);
2128  }
2129 
2130  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
2131  {
2132  query += wordlen;
2133 
2134  query = skip_white_space(query);
2135 
2136  wordlen = 0;
2137  while (isalpha((unsigned char) query[wordlen]))
2138  wordlen += PQmblen(&query[wordlen], pset.encoding);
2139 
2140  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2141  return true;
2142  }
2143 
2144  return false;
2145  }
2146 
2147  if (wordlen == 5 && pg_strncasecmp(query, "alter", 5) == 0)
2148  {
2149  query += wordlen;
2150 
2151  query = skip_white_space(query);
2152 
2153  wordlen = 0;
2154  while (isalpha((unsigned char) query[wordlen]))
2155  wordlen += PQmblen(&query[wordlen], pset.encoding);
2156 
2157  /* ALTER SYSTEM isn't allowed in xacts */
2158  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2159  return true;
2160 
2161  return false;
2162  }
2163 
2164  /*
2165  * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
2166  * aren't really valid commands so we don't care much. The other four
2167  * possible matches are correct.
2168  */
2169  if ((wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
2170  (wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
2171  {
2172  query += wordlen;
2173 
2174  query = skip_white_space(query);
2175 
2176  wordlen = 0;
2177  while (isalpha((unsigned char) query[wordlen]))
2178  wordlen += PQmblen(&query[wordlen], pset.encoding);
2179 
2180  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
2181  return true;
2182  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2183  return true;
2184  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
2185  return true;
2186  if (wordlen == 5 && (pg_strncasecmp(query, "index", 5) == 0 ||
2187  pg_strncasecmp(query, "table", 5) == 0))
2188  {
2189  query += wordlen;
2190  query = skip_white_space(query);
2191  wordlen = 0;
2192  while (isalpha((unsigned char) query[wordlen]))
2193  wordlen += PQmblen(&query[wordlen], pset.encoding);
2194 
2195  /*
2196  * REINDEX [ TABLE | INDEX ] CONCURRENTLY are not allowed in
2197  * xacts.
2198  */
2199  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2200  return true;
2201  }
2202 
2203  /* DROP INDEX CONCURRENTLY isn't allowed in xacts */
2204  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
2205  {
2206  query += wordlen;
2207 
2208  query = skip_white_space(query);
2209 
2210  wordlen = 0;
2211  while (isalpha((unsigned char) query[wordlen]))
2212  wordlen += PQmblen(&query[wordlen], pset.encoding);
2213 
2214  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2215  return true;
2216 
2217  return false;
2218  }
2219 
2220  return false;
2221  }
2222 
2223  /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */
2224  if (wordlen == 7 && pg_strncasecmp(query, "discard", 7) == 0)
2225  {
2226  query += wordlen;
2227 
2228  query = skip_white_space(query);
2229 
2230  wordlen = 0;
2231  while (isalpha((unsigned char) query[wordlen]))
2232  wordlen += PQmblen(&query[wordlen], pset.encoding);
2233 
2234  if (wordlen == 3 && pg_strncasecmp(query, "all", 3) == 0)
2235  return true;
2236  return false;
2237  }
2238 
2239  return false;
2240 }
PsqlSettings pset
Definition: startup.c:31
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
int encoding
Definition: settings.h:84
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1216
static const char * skip_white_space(const char *query)
Definition: common.c:1968

◆ ConnectionUp()

static bool ConnectionUp ( void  )
static

Definition at line 366 of file common.c.

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

Referenced by CheckConnection(), and SendQuery().

367 {
368  return PQstatus(pset.db) != CONNECTION_BAD;
369 }
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6564

◆ DescribeQuery()

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

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

1591 {
1592  PGresult *results;
1593  bool OK;
1595  after;
1596 
1597  *elapsed_msec = 0;
1598 
1599  if (pset.timing)
1600  INSTR_TIME_SET_CURRENT(before);
1601 
1602  /*
1603  * To parse the query but not execute it, we prepare it, using the unnamed
1604  * prepared statement. This is invisible to psql users, since there's no
1605  * way to access the unnamed prepared statement from psql user space. The
1606  * next Parse or Query protocol message would overwrite the statement
1607  * anyway. (So there's no great need to clear it when done, which is a
1608  * good thing because libpq provides no easy way to do that.)
1609  */
1610  results = PQprepare(pset.db, "", query, 0, NULL);
1611  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1612  {
1614  SetResultVariables(results, false);
1615  ClearOrSaveResult(results);
1616  return false;
1617  }
1618  PQclear(results);
1619 
1620  results = PQdescribePrepared(pset.db, "");
1621  OK = AcceptResult(results) &&
1622  (PQresultStatus(results) == PGRES_COMMAND_OK);
1623  if (OK && results)
1624  {
1625  if (PQnfields(results) > 0)
1626  {
1628  int i;
1629 
1630  initPQExpBuffer(&buf);
1631 
1632  printfPQExpBuffer(&buf,
1633  "SELECT name AS \"%s\", pg_catalog.format_type(tp, tpm) AS \"%s\"\n"
1634  "FROM (VALUES ",
1635  gettext_noop("Column"),
1636  gettext_noop("Type"));
1637 
1638  for (i = 0; i < PQnfields(results); i++)
1639  {
1640  const char *name;
1641  char *escname;
1642 
1643  if (i > 0)
1644  appendPQExpBufferStr(&buf, ",");
1645 
1646  name = PQfname(results, i);
1647  escname = PQescapeLiteral(pset.db, name, strlen(name));
1648 
1649  if (escname == NULL)
1650  {
1652  PQclear(results);
1653  termPQExpBuffer(&buf);
1654  return false;
1655  }
1656 
1657  appendPQExpBuffer(&buf, "(%s, '%u'::pg_catalog.oid, %d)",
1658  escname,
1659  PQftype(results, i),
1660  PQfmod(results, i));
1661 
1662  PQfreemem(escname);
1663  }
1664 
1665  appendPQExpBufferStr(&buf, ") s(name, tp, tpm)");
1666  PQclear(results);
1667 
1668  results = PQexec(pset.db, buf.data);
1669  OK = AcceptResult(results);
1670 
1671  if (pset.timing)
1672  {
1673  INSTR_TIME_SET_CURRENT(after);
1674  INSTR_TIME_SUBTRACT(after, before);
1675  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1676  }
1677 
1678  if (OK && results)
1679  OK = PrintQueryResults(results);
1680 
1681  termPQExpBuffer(&buf);
1682  }
1683  else
1685  _("The command has no result, or the result has no columns.\n"));
1686  }
1687 
1688  SetResultVariables(results, OK);
1689  ClearOrSaveResult(results);
1690 
1691  return OK;
1692 }
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1241
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2777
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
Definition: fe-exec.c:1983
PGconn * db
Definition: settings.h:83
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
Definition: fe-exec.c:2156
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:596
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2855
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
static void SetResultVariables(PGresult *results, bool success)
Definition: common.c:554
#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:1142
FILE * queryFout
Definition: settings.h:85
#define fprintf
Definition: port.h:196
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
static bool AcceptResult(const PGresult *result)
Definition: common.c:497
static int before(chr x, chr y)
Definition: regc_locale.c:496
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3007
static char * buf
Definition: pg_test_fsync.c:67
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3564
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int PQfmod(const PGresult *res, int field_num)
Definition: fe-exec.c:3029
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
const char * name
Definition: encode.c:521
int i
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define _(x)
Definition: elog.c:87
void PQfreemem(void *ptr)
Definition: fe-exec.c:3296
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
#define pg_log_info(...)
Definition: logging.h:87

◆ ExecQueryTuples()

static bool ExecQueryTuples ( const PGresult result)
static

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

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

◆ ExecQueryUsingCursor()

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

Definition at line 1706 of file common.c.

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

Referenced by SendQuery().

1707 {
1708  bool OK = true;
1709  PGresult *results;
1711  printQueryOpt my_popt = pset.popt;
1712  FILE *fout;
1713  bool is_pipe;
1714  bool is_pager = false;
1715  bool started_txn = false;
1716  int64 total_tuples = 0;
1717  int ntuples;
1718  int fetch_count;
1719  char fetch_cmd[64];
1721  after;
1722  int flush_error;
1723 
1724  *elapsed_msec = 0;
1725 
1726  /* initialize print options for partial table output */
1727  my_popt.topt.start_table = true;
1728  my_popt.topt.stop_table = false;
1729  my_popt.topt.prior_records = 0;
1730 
1731  if (pset.timing)
1732  INSTR_TIME_SET_CURRENT(before);
1733 
1734  /* if we're not in a transaction, start one */
1736  {
1737  results = PQexec(pset.db, "BEGIN");
1738  OK = AcceptResult(results) &&
1739  (PQresultStatus(results) == PGRES_COMMAND_OK);
1740  ClearOrSaveResult(results);
1741  if (!OK)
1742  return false;
1743  started_txn = true;
1744  }
1745 
1746  /* Send DECLARE CURSOR */
1747  initPQExpBuffer(&buf);
1748  appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1749  query);
1750 
1751  results = PQexec(pset.db, buf.data);
1752  OK = AcceptResult(results) &&
1753  (PQresultStatus(results) == PGRES_COMMAND_OK);
1754  if (!OK)
1755  SetResultVariables(results, OK);
1756  ClearOrSaveResult(results);
1757  termPQExpBuffer(&buf);
1758  if (!OK)
1759  goto cleanup;
1760 
1761  if (pset.timing)
1762  {
1763  INSTR_TIME_SET_CURRENT(after);
1764  INSTR_TIME_SUBTRACT(after, before);
1765  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1766  }
1767 
1768  /*
1769  * In \gset mode, we force the fetch count to be 2, so that we will throw
1770  * the appropriate error if the query returns more than one row.
1771  */
1772  if (pset.gset_prefix)
1773  fetch_count = 2;
1774  else
1775  fetch_count = pset.fetch_count;
1776 
1777  snprintf(fetch_cmd, sizeof(fetch_cmd),
1778  "FETCH FORWARD %d FROM _psql_cursor",
1779  fetch_count);
1780 
1781  /* one-shot expanded output requested via \gx */
1782  if (pset.g_expanded)
1783  my_popt.topt.expanded = 1;
1784 
1785  /* prepare to write output to \g argument, if any */
1786  if (pset.gfname)
1787  {
1788  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
1789  {
1790  OK = false;
1791  goto cleanup;
1792  }
1793  if (is_pipe)
1795  }
1796  else
1797  {
1798  fout = pset.queryFout;
1799  is_pipe = false; /* doesn't matter */
1800  }
1801 
1802  /* clear any pre-existing error indication on the output stream */
1803  clearerr(fout);
1804 
1805  for (;;)
1806  {
1807  if (pset.timing)
1808  INSTR_TIME_SET_CURRENT(before);
1809 
1810  /* get fetch_count tuples at a time */
1811  results = PQexec(pset.db, fetch_cmd);
1812 
1813  if (pset.timing)
1814  {
1815  INSTR_TIME_SET_CURRENT(after);
1816  INSTR_TIME_SUBTRACT(after, before);
1817  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1818  }
1819 
1820  if (PQresultStatus(results) != PGRES_TUPLES_OK)
1821  {
1822  /* shut down pager before printing error message */
1823  if (is_pager)
1824  {
1825  ClosePager(fout);
1826  is_pager = false;
1827  }
1828 
1829  OK = AcceptResult(results);
1830  Assert(!OK);
1831  SetResultVariables(results, OK);
1832  ClearOrSaveResult(results);
1833  break;
1834  }
1835 
1836  if (pset.gset_prefix)
1837  {
1838  /* StoreQueryTuple will complain if not exactly one row */
1839  OK = StoreQueryTuple(results);
1840  ClearOrSaveResult(results);
1841  break;
1842  }
1843 
1844  /*
1845  * Note we do not deal with \gdesc, \gexec or \crosstabview modes here
1846  */
1847 
1848  ntuples = PQntuples(results);
1849  total_tuples += ntuples;
1850 
1851  if (ntuples < fetch_count)
1852  {
1853  /* this is the last result set, so allow footer decoration */
1854  my_popt.topt.stop_table = true;
1855  }
1856  else if (fout == stdout && !is_pager)
1857  {
1858  /*
1859  * If query requires multiple result sets, hack to ensure that
1860  * only one pager instance is used for the whole mess
1861  */
1862  fout = PageOutput(INT_MAX, &(my_popt.topt));
1863  is_pager = true;
1864  }
1865 
1866  printQuery(results, &my_popt, fout, is_pager, pset.logfile);
1867 
1868  ClearOrSaveResult(results);
1869 
1870  /* after the first result set, disallow header decoration */
1871  my_popt.topt.start_table = false;
1872  my_popt.topt.prior_records += ntuples;
1873 
1874  /*
1875  * Make sure to flush the output stream, so intermediate results are
1876  * visible to the client immediately. We check the results because if
1877  * the pager dies/exits/etc, there's no sense throwing more data at
1878  * it.
1879  */
1880  flush_error = fflush(fout);
1881 
1882  /*
1883  * Check if we are at the end, if a cancel was pressed, or if there
1884  * were any errors either trying to flush out the results, or more
1885  * generally on the output stream at all. If we hit any errors
1886  * writing things to the stream, we presume $PAGER has disappeared and
1887  * stop bothering to pull down more data.
1888  */
1889  if (ntuples < fetch_count || cancel_pressed || flush_error ||
1890  ferror(fout))
1891  break;
1892  }
1893 
1894  if (pset.gfname)
1895  {
1896  /* close \g argument file/pipe */
1897  if (is_pipe)
1898  {
1899  pclose(fout);
1901  }
1902  else
1903  fclose(fout);
1904  }
1905  else if (is_pager)
1906  {
1907  /* close transient pager */
1908  ClosePager(fout);
1909  }
1910 
1911  if (OK)
1912  {
1913  /*
1914  * We don't have a PGresult here, and even if we did it wouldn't have
1915  * the right row count, so fake SetResultVariables(). In error cases,
1916  * we already set the result variables above.
1917  */
1918  char buf[32];
1919 
1920  SetVariable(pset.vars, "ERROR", "false");
1921  SetVariable(pset.vars, "SQLSTATE", "00000");
1922  snprintf(buf, sizeof(buf), INT64_FORMAT, total_tuples);
1923  SetVariable(pset.vars, "ROW_COUNT", buf);
1924  }
1925 
1926 cleanup:
1927  if (pset.timing)
1928  INSTR_TIME_SET_CURRENT(before);
1929 
1930  /*
1931  * We try to close the cursor on either success or failure, but on failure
1932  * ignore the result (it's probably just a bleat about being in an aborted
1933  * transaction)
1934  */
1935  results = PQexec(pset.db, "CLOSE _psql_cursor");
1936  if (OK)
1937  {
1938  OK = AcceptResult(results) &&
1939  (PQresultStatus(results) == PGRES_COMMAND_OK);
1940  ClearOrSaveResult(results);
1941  }
1942  else
1943  PQclear(results);
1944 
1945  if (started_txn)
1946  {
1947  results = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK");
1948  OK &= AcceptResult(results) &&
1949  (PQresultStatus(results) == PGRES_COMMAND_OK);
1950  ClearOrSaveResult(results);
1951  }
1952 
1953  if (pset.timing)
1954  {
1955  INSTR_TIME_SET_CURRENT(after);
1956  INSTR_TIME_SUBTRACT(after, before);
1957  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1958  }
1959 
1960  return OK;
1961 }
char * gset_prefix
Definition: settings.h:96
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:596
void disable_sigpipe_trap(void)
Definition: print.c:2942
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void ClosePager(FILE *pagerpipe)
Definition: print.c:3043
static void SetResultVariables(PGresult *results, bool success)
Definition: common.c:554
#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:109
printTableOpt topt
Definition: print.h:167
FILE * queryFout
Definition: settings.h:85
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
unsigned long prior_records
Definition: print.h:112
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
static bool AcceptResult(const PGresult *result)
Definition: common.c:497
volatile bool cancel_pressed
Definition: print.c:44
static int before(chr x, chr y)
Definition: regc_locale.c:496
unsigned short int expanded
Definition: print.h:100
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:2992
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static char * buf
Definition: pg_test_fsync.c:67
int fetch_count
Definition: settings.h:131
bool g_expanded
Definition: settings.h:95
void restore_sigpipe_trap(void)
Definition: print.c:2965
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6572
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:49
char * gfname
Definition: settings.h:94
static void cleanup(void)
Definition: bootstrap.c:901
FILE * logfile
Definition: settings.h:116
void PQclear(PGresult *res)
Definition: fe-exec.c:694
bool stop_table
Definition: print.h:110
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
#define Assert(condition)
Definition: c.h:733
printQueryOpt popt
Definition: settings.h:92
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3434
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
#define INT64_FORMAT
Definition: c.h:401
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:895
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define snprintf
Definition: port.h:192
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
VariableSpace vars
Definition: settings.h:118

◆ expand_tilde()

void expand_tilde ( char **  filename)

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

2356 {
2357  if (!filename || !(*filename))
2358  return;
2359 
2360  /*
2361  * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2362  * for short versions of long file names, though the tilde is usually
2363  * toward the end, not at the beginning.
2364  */
2365 #ifndef WIN32
2366 
2367  /* try tilde expansion */
2368  if (**filename == '~')
2369  {
2370  char *fn;
2371  char oldp,
2372  *p;
2373  struct passwd *pw;
2374  char home[MAXPGPATH];
2375 
2376  fn = *filename;
2377  *home = '\0';
2378 
2379  p = fn + 1;
2380  while (*p != '/' && *p != '\0')
2381  p++;
2382 
2383  oldp = *p;
2384  *p = '\0';
2385 
2386  if (*(fn + 1) == '\0')
2387  get_home_path(home); /* ~ or ~/ only */
2388  else if ((pw = getpwnam(fn + 1)) != NULL)
2389  strlcpy(home, pw->pw_dir, sizeof(home)); /* ~user */
2390 
2391  *p = oldp;
2392  if (strlen(home) != 0)
2393  {
2394  char *newfn;
2395 
2396  newfn = psprintf("%s%s", home, p);
2397  free(fn);
2398  *filename = newfn;
2399  }
2400  }
2401 #endif
2402 
2403  return;
2404 }
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 278 of file common.c.

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

Referenced by setup_cancel_handler().

279 {
280  int save_errno = errno;
281  char errbuf[256];
282 
283  /* if we are waiting for input, longjmp out of it */
285  {
286  sigint_interrupt_enabled = false;
287  siglongjmp(sigint_interrupt_jmp, 1);
288  }
289 
290  /* else, set cancel flag to stop any long-running loops */
291  cancel_pressed = true;
292 
293  /* and send QueryCancel if we are processing a database query */
294  if (cancelConn != NULL)
295  {
296  if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
297  write_stderr("Cancel request sent\n");
298  else
299  {
300  write_stderr("Could not send cancel request: ");
301  write_stderr(errbuf);
302  }
303  }
304 
305  errno = save_errno; /* just in case the write changed it */
306 }
volatile bool sigint_interrupt_enabled
Definition: common.c:251
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:253
volatile bool cancel_pressed
Definition: print.c:44
#define write_stderr(str)
Definition: common.c:266
static PGcancel *volatile cancelConn
Definition: common.c:255
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
Definition: fe-connect.c:4395

◆ is_select_command()

static bool is_select_command ( const char *  query)
static

Definition at line 2247 of file common.c.

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

Referenced by SendQuery().

2248 {
2249  int wordlen;
2250 
2251  /*
2252  * First advance over any whitespace, comments and left parentheses.
2253  */
2254  for (;;)
2255  {
2256  query = skip_white_space(query);
2257  if (query[0] == '(')
2258  query++;
2259  else
2260  break;
2261  }
2262 
2263  /*
2264  * Check word length (since "selectx" is not "select").
2265  */
2266  wordlen = 0;
2267  while (isalpha((unsigned char) query[wordlen]))
2268  wordlen += PQmblen(&query[wordlen], pset.encoding);
2269 
2270  if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
2271  return true;
2272 
2273  if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
2274  return true;
2275 
2276  return false;
2277 }
PsqlSettings pset
Definition: startup.c:31
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
int encoding
Definition: settings.h:84
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1216
static const char * skip_white_space(const char *query)
Definition: common.c:1968

◆ is_superuser()

bool is_superuser ( void  )

Definition at line 2287 of file common.c.

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

2288 {
2289  const char *val;
2290 
2291  if (!pset.db)
2292  return false;
2293 
2294  val = PQparameterStatus(pset.db, "is_superuser");
2295 
2296  if (val && strcmp(val, "on") == 0)
2297  return true;
2298 
2299  return false;
2300 }
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6582
long val
Definition: informix.c:684

◆ NoticeProcessor()

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

Definition at line 219 of file common.c.

References pg_log_info.

Referenced by do_connect(), and main().

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

◆ openQueryOutputFile()

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

Definition at line 49 of file common.c.

References pg_log_error, and generate_unaccent_rules::stdout.

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

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

◆ PrintNotifications()

static void PrintNotifications ( void  )
static

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

827 {
828  PGnotify *notify;
829 
831  while ((notify = PQnotifies(pset.db)) != NULL)
832  {
833  /* for backward compatibility, only show payload if nonempty */
834  if (notify->extra[0])
835  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
836  notify->relname, notify->extra, notify->be_pid);
837  else
838  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
839  notify->relname, notify->be_pid);
840  fflush(pset.queryFout);
841  PQfreemem(notify);
843  }
844 }
char * extra
Definition: libpq-fe.h:168
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
PGnotify * PQnotifies(PGconn *conn)
Definition: fe-exec.c:2289
FILE * queryFout
Definition: settings.h:85
#define fprintf
Definition: port.h:196
int be_pid
Definition: libpq-fe.h:167
char * relname
Definition: libpq-fe.h:166
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1704
#define _(x)
Definition: elog.c:87
void PQfreemem(void *ptr)
Definition: fe-exec.c:3296

◆ PrintQueryResults()

static bool PrintQueryResults ( PGresult results)
static

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

1242 {
1243  bool success;
1244  const char *cmdstatus;
1245 
1246  if (!results)
1247  return false;
1248 
1249  switch (PQresultStatus(results))
1250  {
1251  case PGRES_TUPLES_OK:
1252  /* store or execute or print the data ... */
1253  if (pset.gset_prefix)
1254  success = StoreQueryTuple(results);
1255  else if (pset.gexec_flag)
1256  success = ExecQueryTuples(results);
1257  else if (pset.crosstab_flag)
1258  success = PrintResultsInCrosstab(results);
1259  else
1260  success = PrintQueryTuples(results);
1261  /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
1262  cmdstatus = PQcmdStatus(results);
1263  if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
1264  strncmp(cmdstatus, "UPDATE", 6) == 0 ||
1265  strncmp(cmdstatus, "DELETE", 6) == 0)
1266  PrintQueryStatus(results);
1267  break;
1268 
1269  case PGRES_COMMAND_OK:
1270  PrintQueryStatus(results);
1271  success = true;
1272  break;
1273 
1274  case PGRES_EMPTY_QUERY:
1275  success = true;
1276  break;
1277 
1278  case PGRES_COPY_OUT:
1279  case PGRES_COPY_IN:
1280  /* nothing to do here */
1281  success = true;
1282  break;
1283 
1284  case PGRES_BAD_RESPONSE:
1285  case PGRES_NONFATAL_ERROR:
1286  case PGRES_FATAL_ERROR:
1287  success = false;
1288  break;
1289 
1290  default:
1291  success = false;
1292  pg_log_error("unexpected PQresultStatus: %d",
1293  PQresultStatus(results));
1294  break;
1295  }
1296 
1297  fflush(pset.queryFout);
1298 
1299  return success;
1300 }
static void PrintQueryStatus(PGresult *results)
Definition: common.c:1209
char * gset_prefix
Definition: settings.h:96
PsqlSettings pset
Definition: startup.c:31
#define pg_log_error(...)
Definition: logging.h:79
static bool ExecQueryTuples(const PGresult *result)
Definition: common.c:952
static bool PrintQueryTuples(const PGresult *results)
Definition: common.c:853
bool gexec_flag
Definition: settings.h:98
FILE * queryFout
Definition: settings.h:85
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
bool PrintResultsInCrosstab(const PGresult *res)
Definition: crosstabview.c:103
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:895
bool crosstab_flag
Definition: settings.h:99
static bool success
Definition: initdb.c:163

◆ PrintQueryStatus()

static void PrintQueryStatus ( PGresult results)
static

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

1210 {
1211  char buf[16];
1212 
1213  if (!pset.quiet)
1214  {
1215  if (pset.popt.topt.format == PRINT_HTML)
1216  {
1217  fputs("<p>", pset.queryFout);
1219  fputs("</p>\n", pset.queryFout);
1220  }
1221  else
1222  fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
1223  }
1224 
1225  if (pset.logfile)
1226  fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
1227 
1228  snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
1229  SetVariable(pset.vars, "LASTOID", buf);
1230 }
PsqlSettings pset
Definition: startup.c:31
Oid PQoidValue(const PGresult *res)
Definition: fe-exec.c:3081
enum printFormat format
Definition: print.h:99
printTableOpt topt
Definition: print.h:167
FILE * queryFout
Definition: settings.h:85
#define fprintf
Definition: port.h:196
static char * buf
Definition: pg_test_fsync.c:67
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
FILE * logfile
Definition: settings.h:116
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
printQueryOpt popt
Definition: settings.h:92
void html_escaped_print(const char *in, FILE *fout)
Definition: print.c:1855
#define snprintf
Definition: port.h:192
VariableSpace vars
Definition: settings.h:118

◆ PrintQueryTuples()

static bool PrintQueryTuples ( const PGresult results)
static

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

854 {
855  printQueryOpt my_popt = pset.popt;
856 
857  /* one-shot expanded output requested via \gx */
858  if (pset.g_expanded)
859  my_popt.topt.expanded = 1;
860 
861  /* write output to \g argument, if any */
862  if (pset.gfname)
863  {
864  FILE *fout;
865  bool is_pipe;
866 
867  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
868  return false;
869  if (is_pipe)
871 
872  printQuery(results, &my_popt, fout, false, pset.logfile);
873 
874  if (is_pipe)
875  {
876  pclose(fout);
878  }
879  else
880  fclose(fout);
881  }
882  else
883  printQuery(results, &my_popt, pset.queryFout, false, pset.logfile);
884 
885  return true;
886 }
PsqlSettings pset
Definition: startup.c:31
void disable_sigpipe_trap(void)
Definition: print.c:2942
printTableOpt topt
Definition: print.h:167
FILE * queryFout
Definition: settings.h:85
unsigned short int expanded
Definition: print.h:100
bool g_expanded
Definition: settings.h:95
void restore_sigpipe_trap(void)
Definition: print.c:2965
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:49
char * gfname
Definition: settings.h:94
FILE * logfile
Definition: settings.h:116
printQueryOpt popt
Definition: settings.h:92
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3434

◆ PrintTiming()

static void PrintTiming ( double  elapsed_msec)
static

Definition at line 622 of file common.c.

References _, days, and printf.

Referenced by PSQLexecWatch(), and SendQuery().

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

◆ ProcessResult()

static bool ProcessResult ( PGresult **  results)
static

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

1037 {
1038  bool success = true;
1039  bool first_cycle = true;
1040 
1041  for (;;)
1042  {
1043  ExecStatusType result_status;
1044  bool is_copy;
1045  PGresult *next_result;
1046 
1047  if (!AcceptResult(*results))
1048  {
1049  /*
1050  * Failure at this point is always a server-side failure or a
1051  * failure to submit the command string. Either way, we're
1052  * finished with this command string.
1053  */
1054  success = false;
1055  break;
1056  }
1057 
1058  result_status = PQresultStatus(*results);
1059  switch (result_status)
1060  {
1061  case PGRES_EMPTY_QUERY:
1062  case PGRES_COMMAND_OK:
1063  case PGRES_TUPLES_OK:
1064  is_copy = false;
1065  break;
1066 
1067  case PGRES_COPY_OUT:
1068  case PGRES_COPY_IN:
1069  is_copy = true;
1070  break;
1071 
1072  default:
1073  /* AcceptResult() should have caught anything else. */
1074  is_copy = false;
1075  pg_log_error("unexpected PQresultStatus: %d", result_status);
1076  break;
1077  }
1078 
1079  if (is_copy)
1080  {
1081  /*
1082  * Marshal the COPY data. Either subroutine will get the
1083  * connection out of its COPY state, then call PQresultStatus()
1084  * once and report any error.
1085  *
1086  * For COPY OUT, direct the output to pset.copyStream if it's set,
1087  * otherwise to pset.gfname if it's set, otherwise to queryFout.
1088  * For COPY IN, use pset.copyStream as data source if it's set,
1089  * otherwise cur_cmd_source.
1090  */
1091  FILE *copystream;
1092  PGresult *copy_result;
1093 
1094  SetCancelConn();
1095  if (result_status == PGRES_COPY_OUT)
1096  {
1097  bool need_close = false;
1098  bool is_pipe = false;
1099 
1100  if (pset.copyStream)
1101  {
1102  /* invoked by \copy */
1103  copystream = pset.copyStream;
1104  }
1105  else if (pset.gfname)
1106  {
1107  /* invoked by \g */
1109  &copystream, &is_pipe))
1110  {
1111  need_close = true;
1112  if (is_pipe)
1114  }
1115  else
1116  copystream = NULL; /* discard COPY data entirely */
1117  }
1118  else
1119  {
1120  /* fall back to the generic query output stream */
1121  copystream = pset.queryFout;
1122  }
1123 
1124  success = handleCopyOut(pset.db,
1125  copystream,
1126  &copy_result)
1127  && success
1128  && (copystream != NULL);
1129 
1130  /*
1131  * Suppress status printing if the report would go to the same
1132  * place as the COPY data just went. Note this doesn't
1133  * prevent error reporting, since handleCopyOut did that.
1134  */
1135  if (copystream == pset.queryFout)
1136  {
1137  PQclear(copy_result);
1138  copy_result = NULL;
1139  }
1140 
1141  if (need_close)
1142  {
1143  /* close \g argument file/pipe */
1144  if (is_pipe)
1145  {
1146  pclose(copystream);
1148  }
1149  else
1150  {
1151  fclose(copystream);
1152  }
1153  }
1154  }
1155  else
1156  {
1157  /* COPY IN */
1158  copystream = pset.copyStream ? pset.copyStream : pset.cur_cmd_source;
1159  success = handleCopyIn(pset.db,
1160  copystream,
1161  PQbinaryTuples(*results),
1162  &copy_result) && success;
1163  }
1164  ResetCancelConn();
1165 
1166  /*
1167  * Replace the PGRES_COPY_OUT/IN result with COPY command's exit
1168  * status, or with NULL if we want to suppress printing anything.
1169  */
1170  PQclear(*results);
1171  *results = copy_result;
1172  }
1173  else if (first_cycle)
1174  {
1175  /* fast path: no COPY commands; PQexec visited all results */
1176  break;
1177  }
1178 
1179  /*
1180  * Check PQgetResult() again. In the typical case of a single-command
1181  * string, it will return NULL. Otherwise, we'll have other results
1182  * to process that may include other COPYs. We keep the last result.
1183  */
1184  next_result = PQgetResult(pset.db);
1185  if (!next_result)
1186  break;
1187 
1188  PQclear(*results);
1189  *results = next_result;
1190  first_cycle = false;
1191  }
1192 
1193  SetResultVariables(*results, success);
1194 
1195  /* may need this to recover from conn loss during COPY */
1196  if (!first_cycle && !CheckConnection())
1197  return false;
1198 
1199  return success;
1200 }
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
void disable_sigpipe_trap(void)
Definition: print.c:2942
#define pg_log_error(...)
Definition: logging.h:79
static void SetResultVariables(PGresult *results, bool success)
Definition: common.c:554
FILE * queryFout
Definition: settings.h:85
static bool CheckConnection(void)
Definition: common.c:384
ExecStatusType
Definition: libpq-fe.h:84
int PQbinaryTuples(const PGresult *res)
Definition: fe-exec.c:2785
FILE * copyStream
Definition: settings.h:88
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
FILE * cur_cmd_source
Definition: settings.h:105
static bool AcceptResult(const PGresult *result)
Definition: common.c:497
bool handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res)
Definition: copy.c:436
void SetCancelConn(void)
Definition: common.c:437
void restore_sigpipe_trap(void)
Definition: print.c:2965
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:49
char * gfname
Definition: settings.h:94
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:163
void ResetCancelConn(void)
Definition: common.c:467
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1778

◆ psql_get_variable()

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

Definition at line 128 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.

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

◆ PSQLexec()

PGresult* PSQLexec ( const char *  query)

Definition at line 681 of file common.c.

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

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

682 {
683  PGresult *res;
684 
685  if (!pset.db)
686  {
687  pg_log_error("You are currently not connected to a database.");
688  return NULL;
689  }
690 
692  {
693  printf(_("********* QUERY **********\n"
694  "%s\n"
695  "**************************\n\n"), query);
696  fflush(stdout);
697  if (pset.logfile)
698  {
700  _("********* QUERY **********\n"
701  "%s\n"
702  "**************************\n\n"), query);
703  fflush(pset.logfile);
704  }
705 
707  return NULL;
708  }
709 
710  SetCancelConn();
711 
712  res = PQexec(pset.db, query);
713 
714  ResetCancelConn();
715 
716  if (!AcceptResult(res))
717  {
718  ClearOrSaveResult(res);
719  res = NULL;
720  }
721 
722  return res;
723 }
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:596
#define pg_log_error(...)
Definition: logging.h:79
#define printf(...)
Definition: port.h:198
#define fprintf
Definition: port.h:196
static bool AcceptResult(const PGresult *result)
Definition: common.c:497
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:135
void SetCancelConn(void)
Definition: common.c:437
FILE * logfile
Definition: settings.h:116
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
void ResetCancelConn(void)
Definition: common.c:467
#define _(x)
Definition: elog.c:87

◆ PSQLexecWatch()

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

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

737 {
738  PGresult *res;
739  double elapsed_msec = 0;
741  instr_time after;
742 
743  if (!pset.db)
744  {
745  pg_log_error("You are currently not connected to a database.");
746  return 0;
747  }
748 
749  SetCancelConn();
750 
751  if (pset.timing)
752  INSTR_TIME_SET_CURRENT(before);
753 
754  res = PQexec(pset.db, query);
755 
756  ResetCancelConn();
757 
758  if (!AcceptResult(res))
759  {
760  ClearOrSaveResult(res);
761  return 0;
762  }
763 
764  if (pset.timing)
765  {
766  INSTR_TIME_SET_CURRENT(after);
767  INSTR_TIME_SUBTRACT(after, before);
768  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
769  }
770 
771  /*
772  * If SIGINT is sent while the query is processing, the interrupt will be
773  * consumed. The user's intention, though, is to cancel the entire watch
774  * process, so detect a sent cancellation request and exit in this case.
775  */
776  if (cancel_pressed)
777  {
778  PQclear(res);
779  return 0;
780  }
781 
782  switch (PQresultStatus(res))
783  {
784  case PGRES_TUPLES_OK:
785  printQuery(res, opt, pset.queryFout, false, pset.logfile);
786  break;
787 
788  case PGRES_COMMAND_OK:
789  fprintf(pset.queryFout, "%s\n%s\n\n", opt->title, PQcmdStatus(res));
790  break;
791 
792  case PGRES_EMPTY_QUERY:
793  pg_log_error("\\watch cannot be used with an empty query");
794  PQclear(res);
795  return -1;
796 
797  case PGRES_COPY_OUT:
798  case PGRES_COPY_IN:
799  case PGRES_COPY_BOTH:
800  pg_log_error("\\watch cannot be used with COPY");
801  PQclear(res);
802  return -1;
803 
804  default:
805  pg_log_error("unexpected result status for \\watch");
806  PQclear(res);
807  return -1;
808  }
809 
810  PQclear(res);
811 
812  fflush(pset.queryFout);
813 
814  /* Possible microtiming output */
815  if (pset.timing)
816  PrintTiming(elapsed_msec);
817 
818  return 1;
819 }
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:596
#define pg_log_error(...)
Definition: logging.h:79
#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:622
FILE * queryFout
Definition: settings.h:85
#define fprintf
Definition: port.h:196
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
static bool AcceptResult(const PGresult *result)
Definition: common.c:497
volatile bool cancel_pressed
Definition: print.c:44
static int before(chr x, chr y)
Definition: regc_locale.c:496
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
void SetCancelConn(void)
Definition: common.c:437
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
FILE * logfile
Definition: settings.h:116
void PQclear(PGresult *res)
Definition: fe-exec.c:694
char * title
Definition: print.h:169
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3434
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
void ResetCancelConn(void)
Definition: common.c:467

◆ recognized_connection_string()

static bool recognized_connection_string ( const char *  connstr)

Definition at line 2442 of file common.c.

References uri_prefix_length().

Referenced by do_connect().

2443 {
2444  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
2445 }
static int uri_prefix_length(const char *connstr)
Definition: common.c:2415
static char * connstr
Definition: pg_dumpall.c:61

◆ ResetCancelConn()

void ResetCancelConn ( void  )

Definition at line 467 of file common.c.

Referenced by CheckConnection(), consumeQueryResult(), do_connect(), do_lo_export(), do_lo_import(), do_lo_unlink(), executeMaintenanceCommand(), ParallelSlotsGetIdle(), ProcessResult(), PSQLexec(), PSQLexecWatch(), and SendQuery().

468 {
469  PGcancel *oldCancelConn;
470 
471 #ifdef WIN32
472  EnterCriticalSection(&cancelConnLock);
473 #endif
474 
475  oldCancelConn = cancelConn;
476  /* be sure handle_sigint doesn't use pointer while freeing */
477  cancelConn = NULL;
478 
479  if (oldCancelConn != NULL)
480  PQfreeCancel(oldCancelConn);
481 
482 #ifdef WIN32
483  LeaveCriticalSection(&cancelConnLock);
484 #endif
485 }
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:4263
static PGcancel *volatile cancelConn
Definition: common.c:255

◆ SendQuery()

bool SendQuery ( const char *  query)

Definition at line 1316 of file common.c.

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

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

1317 {
1318  PGresult *results;
1319  PGTransactionStatusType transaction_status;
1320  double elapsed_msec = 0;
1321  bool OK = false;
1322  int i;
1323  bool on_error_rollback_savepoint = false;
1324  static bool on_error_rollback_warning = false;
1325 
1326  if (!pset.db)
1327  {
1328  pg_log_error("You are currently not connected to a database.");
1329  goto sendquery_cleanup;
1330  }
1331 
1332  if (pset.singlestep)
1333  {
1334  char buf[3];
1335 
1336  fflush(stderr);
1337  printf(_("***(Single step mode: verify command)*******************************************\n"
1338  "%s\n"
1339  "***(press return to proceed or enter x and return to cancel)********************\n"),
1340  query);
1341  fflush(stdout);
1342  if (fgets(buf, sizeof(buf), stdin) != NULL)
1343  if (buf[0] == 'x')
1344  goto sendquery_cleanup;
1345  if (cancel_pressed)
1346  goto sendquery_cleanup;
1347  }
1348  else if (pset.echo == PSQL_ECHO_QUERIES)
1349  {
1350  puts(query);
1351  fflush(stdout);
1352  }
1353 
1354  if (pset.logfile)
1355  {
1357  _("********* QUERY **********\n"
1358  "%s\n"
1359  "**************************\n\n"), query);
1360  fflush(pset.logfile);
1361  }
1362 
1363  SetCancelConn();
1364 
1365  transaction_status = PQtransactionStatus(pset.db);
1366 
1367  if (transaction_status == PQTRANS_IDLE &&
1368  !pset.autocommit &&
1369  !command_no_begin(query))
1370  {
1371  results = PQexec(pset.db, "BEGIN");
1372  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1373  {
1375  ClearOrSaveResult(results);
1376  ResetCancelConn();
1377  goto sendquery_cleanup;
1378  }
1379  ClearOrSaveResult(results);
1380  transaction_status = PQtransactionStatus(pset.db);
1381  }
1382 
1383  if (transaction_status == PQTRANS_INTRANS &&
1387  {
1388  if (on_error_rollback_warning == false && pset.sversion < 80000)
1389  {
1390  char sverbuf[32];
1391 
1392  pg_log_warning("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.",
1394  sverbuf, sizeof(sverbuf)));
1395  on_error_rollback_warning = true;
1396  }
1397  else
1398  {
1399  results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
1400  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1401  {
1403  ClearOrSaveResult(results);
1404  ResetCancelConn();
1405  goto sendquery_cleanup;
1406  }
1407  ClearOrSaveResult(results);
1408  on_error_rollback_savepoint = true;
1409  }
1410  }
1411 
1412  if (pset.gdesc_flag)
1413  {
1414  /* Describe query's result columns, without executing it */
1415  OK = DescribeQuery(query, &elapsed_msec);
1416  ResetCancelConn();
1417  results = NULL; /* PQclear(NULL) does nothing */
1418  }
1419  else if (pset.fetch_count <= 0 || pset.gexec_flag ||
1421  {
1422  /* Default fetch-it-all-and-print mode */
1424  after;
1425 
1426  if (pset.timing)
1427  INSTR_TIME_SET_CURRENT(before);
1428 
1429  results = PQexec(pset.db, query);
1430 
1431  /* these operations are included in the timing result: */
1432  ResetCancelConn();
1433  OK = ProcessResult(&results);
1434 
1435  if (pset.timing)
1436  {
1437  INSTR_TIME_SET_CURRENT(after);
1438  INSTR_TIME_SUBTRACT(after, before);
1439  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1440  }
1441 
1442  /* but printing results isn't: */
1443  if (OK && results)
1444  OK = PrintQueryResults(results);
1445  }
1446  else
1447  {
1448  /* Fetch-in-segments mode */
1449  OK = ExecQueryUsingCursor(query, &elapsed_msec);
1450  ResetCancelConn();
1451  results = NULL; /* PQclear(NULL) does nothing */
1452  }
1453 
1454  if (!OK && pset.echo == PSQL_ECHO_ERRORS)
1455  pg_log_info("STATEMENT: %s", query);
1456 
1457  /* If we made a temporary savepoint, possibly release/rollback */
1458  if (on_error_rollback_savepoint)
1459  {
1460  const char *svptcmd = NULL;
1461 
1462  transaction_status = PQtransactionStatus(pset.db);
1463 
1464  switch (transaction_status)
1465  {
1466  case PQTRANS_INERROR:
1467  /* We always rollback on an error */
1468  svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
1469  break;
1470 
1471  case PQTRANS_IDLE:
1472  /* If they are no longer in a transaction, then do nothing */
1473  break;
1474 
1475  case PQTRANS_INTRANS:
1476 
1477  /*
1478  * Do nothing if they are messing with savepoints themselves:
1479  * If the user did RELEASE or ROLLBACK, our savepoint is gone.
1480  * If they issued a SAVEPOINT, releasing ours would remove
1481  * theirs.
1482  */
1483  if (results &&
1484  (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
1485  strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
1486  strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
1487  svptcmd = NULL;
1488  else
1489  svptcmd = "RELEASE pg_psql_temporary_savepoint";
1490  break;
1491 
1492  case PQTRANS_ACTIVE:
1493  case PQTRANS_UNKNOWN:
1494  default:
1495  OK = false;
1496  /* PQTRANS_UNKNOWN is expected given a broken connection. */
1497  if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp())
1498  pg_log_error("unexpected transaction status (%d)",
1499  transaction_status);
1500  break;
1501  }
1502 
1503  if (svptcmd)
1504  {
1505  PGresult *svptres;
1506 
1507  svptres = PQexec(pset.db, svptcmd);
1508  if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
1509  {
1511  ClearOrSaveResult(svptres);
1512  OK = false;
1513 
1514  PQclear(results);
1515  ResetCancelConn();
1516  goto sendquery_cleanup;
1517  }
1518  PQclear(svptres);
1519  }
1520  }
1521 
1522  ClearOrSaveResult(results);
1523 
1524  /* Possible microtiming output */
1525  if (pset.timing)
1526  PrintTiming(elapsed_msec);
1527 
1528  /* check for events that may occur during query execution */
1529 
1530  if (pset.encoding != PQclientEncoding(pset.db) &&
1531  PQclientEncoding(pset.db) >= 0)
1532  {
1533  /* track effects of SET CLIENT_ENCODING */
1536  SetVariable(pset.vars, "ENCODING",
1538  }
1539 
1541 
1542  /* perform cleanup that should occur after any attempted query */
1543 
1544 sendquery_cleanup:
1545 
1546  /* reset \g's output-to-filename trigger */
1547  if (pset.gfname)
1548  {
1549  free(pset.gfname);
1550  pset.gfname = NULL;
1551  }
1552 
1553  /* reset \gx's expanded-mode flag */
1554  pset.g_expanded = false;
1555 
1556  /* reset \gset trigger */
1557  if (pset.gset_prefix)
1558  {
1560  pset.gset_prefix = NULL;
1561  }
1562 
1563  /* reset \gdesc trigger */
1564  pset.gdesc_flag = false;
1565 
1566  /* reset \gexec trigger */
1567  pset.gexec_flag = false;
1568 
1569  /* reset \crosstabview trigger */
1570  pset.crosstab_flag = false;
1571  for (i = 0; i < lengthof(pset.ctv_args); i++)
1572  {
1573  pg_free(pset.ctv_args[i]);
1574  pset.ctv_args[i] = NULL;
1575  }
1576 
1577  return OK;
1578 }
PSQL_ECHO echo
Definition: settings.h:134
bool singlestep
Definition: settings.h:129
char * gset_prefix
Definition: settings.h:96
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1241
PGconn * db
Definition: settings.h:83
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
int encoding
Definition: print.h:120
PsqlSettings pset
Definition: startup.c:31
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:596
#define pg_log_error(...)
Definition: logging.h:79
#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:167
static void PrintTiming(double elapsed_msec)
Definition: common.c:622
#define printf(...)
Definition: port.h:198
static bool ConnectionUp(void)
Definition: common.c:366
bool autocommit
Definition: settings.h:125
#define lengthof(array)
Definition: c.h:663
#define fprintf
Definition: port.h:196
PSQL_ERROR_ROLLBACK on_error_rollback
Definition: settings.h:136
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6677
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
volatile bool cancel_pressed
Definition: print.c:44
static void PrintNotifications(void)
Definition: common.c:826
char * ctv_args[4]
Definition: settings.h:100
static int before(chr x, chr y)
Definition: regc_locale.c:496
bool cur_cmd_interactive
Definition: settings.h:107
static bool is_select_command(const char *query)
Definition: common.c:2247
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
bool gdesc_flag
Definition: settings.h:97
static char * buf
Definition: pg_test_fsync.c:67
int fetch_count
Definition: settings.h:131
static bool ProcessResult(PGresult **results)
Definition: common.c:1036
bool g_expanded
Definition: settings.h:95
void SetCancelConn(void)
Definition: common.c:437
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1706
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6572
static bool DescribeQuery(const char *query, double *elapsed_msec)
Definition: common.c:1590
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3040
char * gfname
Definition: settings.h:94
FILE * logfile
Definition: settings.h:116
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:607
PGTransactionStatusType
Definition: libpq-fe.h:103
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
printQueryOpt popt
Definition: settings.h:92
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
int i
bool crosstab_flag
Definition: settings.h:99
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define pg_log_warning(...)
Definition: pgfnames.c:24
int encoding
Definition: settings.h:84
static bool command_no_begin(const char *query)
Definition: common.c:2032
void ResetCancelConn(void)
Definition: common.c:467
#define _(x)
Definition: elog.c:87
#define pg_log_info(...)
Definition: logging.h:87
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:177
VariableSpace vars
Definition: settings.h:118

◆ session_username()

const char* session_username ( void  )

Definition at line 2334 of file common.c.

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

Referenced by get_prompt().

2335 {
2336  const char *val;
2337 
2338  if (!pset.db)
2339  return NULL;
2340 
2341  val = PQparameterStatus(pset.db, "session_authorization");
2342  if (val)
2343  return val;
2344  else
2345  return PQuser(pset.db);
2346 }
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6582
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6475
long val
Definition: informix.c:684

◆ SetCancelConn()

void SetCancelConn ( void  )

Definition at line 437 of file common.c.

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

Referenced by consumeQueryResult(), do_lo_export(), do_lo_import(), do_lo_unlink(), executeMaintenanceCommand(), ParallelSlotsGetIdle(), ProcessResult(), PSQLexec(), PSQLexecWatch(), and SendQuery().

438 {
439  PGcancel *oldCancelConn;
440 
441 #ifdef WIN32
442  EnterCriticalSection(&cancelConnLock);
443 #endif
444 
445  /* Free the old one if we have one */
446  oldCancelConn = cancelConn;
447  /* be sure handle_sigint doesn't use pointer while freeing */
448  cancelConn = NULL;
449 
450  if (oldCancelConn != NULL)
451  PQfreeCancel(oldCancelConn);
452 
454 
455 #ifdef WIN32
456  LeaveCriticalSection(&cancelConnLock);
457 #endif
458 }
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:4263
PGcancel * PQgetCancel(PGconn *conn)
Definition: fe-connect.c:4240
static PGcancel *volatile cancelConn
Definition: common.c:255

◆ setQFout()

bool setQFout ( const char *  fname)

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

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

◆ SetResultVariables()

static void SetResultVariables ( PGresult results,
bool  success 
)
static

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

555 {
556  if (success)
557  {
558  const char *ntuples = PQcmdTuples(results);
559 
560  SetVariable(pset.vars, "ERROR", "false");
561  SetVariable(pset.vars, "SQLSTATE", "00000");
562  SetVariable(pset.vars, "ROW_COUNT", *ntuples ? ntuples : "0");
563  }
564  else
565  {
566  const char *code = PQresultErrorField(results, PG_DIAG_SQLSTATE);
567  const char *mesg = PQresultErrorField(results, PG_DIAG_MESSAGE_PRIMARY);
568 
569  SetVariable(pset.vars, "ERROR", "true");
570 
571  /*
572  * If there is no SQLSTATE code, use an empty string. This can happen
573  * for libpq-detected errors (e.g., lost connection, ENOMEM).
574  */
575  if (code == NULL)
576  code = "";
577  SetVariable(pset.vars, "SQLSTATE", code);
578  SetVariable(pset.vars, "ROW_COUNT", "0");
579  SetVariable(pset.vars, "LAST_ERROR_SQLSTATE", code);
580  SetVariable(pset.vars, "LAST_ERROR_MESSAGE", mesg ? mesg : "");
581  }
582 }
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
PsqlSettings pset
Definition: startup.c:31
char * PQcmdTuples(PGresult *res)
Definition: fe-exec.c:3110
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2754
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
static bool success
Definition: initdb.c:163
VariableSpace vars
Definition: settings.h:118

◆ setup_cancel_handler()

void setup_cancel_handler ( void  )

Definition at line 309 of file common.c.

Referenced by setup_cancel_handler().

310 {
311  pqsignal(SIGINT, handle_sigint);
312 }
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
static void handle_sigint(SIGNAL_ARGS)
Definition: common.c:278

◆ skip_white_space()

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

Definition at line 1968 of file common.c.

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

Referenced by command_no_begin(), and is_select_command().

1969 {
1970  int cnestlevel = 0; /* slash-star comment nest level */
1971 
1972  while (*query)
1973  {
1974  int mblen = PQmblen(query, pset.encoding);
1975 
1976  /*
1977  * Note: we assume the encoding is a superset of ASCII, so that for
1978  * example "query[0] == '/'" is meaningful. However, we do NOT assume
1979  * that the second and subsequent bytes of a multibyte character
1980  * couldn't look like ASCII characters; so it is critical to advance
1981  * by mblen, not 1, whenever we haven't exactly identified the
1982  * character we are skipping over.
1983  */
1984  if (isspace((unsigned char) *query))
1985  query += mblen;
1986  else if (query[0] == '/' && query[1] == '*')
1987  {
1988  cnestlevel++;
1989  query += 2;
1990  }
1991  else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
1992  {
1993  cnestlevel--;
1994  query += 2;
1995  }
1996  else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
1997  {
1998  query += 2;
1999 
2000  /*
2001  * We have to skip to end of line since any slash-star inside the
2002  * -- comment does NOT start a slash-star comment.
2003  */
2004  while (*query)
2005  {
2006  if (*query == '\n')
2007  {
2008  query++;
2009  break;
2010  }
2011  query += PQmblen(query, pset.encoding);
2012  }
2013  }
2014  else if (cnestlevel > 0)
2015  query += mblen;
2016  else
2017  break; /* found first token */
2018  }
2019 
2020  return query;
2021 }
PsqlSettings pset
Definition: startup.c:31
int encoding
Definition: settings.h:84
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1216

◆ standard_strings()

bool standard_strings ( void  )

Definition at line 2310 of file common.c.

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

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

2311 {
2312  const char *val;
2313 
2314  if (!pset.db)
2315  return false;
2316 
2317  val = PQparameterStatus(pset.db, "standard_conforming_strings");
2318 
2319  if (val && strcmp(val, "on") == 0)
2320  return true;
2321 
2322  return false;
2323 }
PGconn * db
Definition: settings.h:83
PsqlSettings pset
Definition: startup.c:31
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6582
long val
Definition: informix.c:684

◆ StoreQueryTuple()

static bool StoreQueryTuple ( const PGresult result)
static

Definition at line 895 of file common.c.

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

Referenced by ExecQueryUsingCursor(), and PrintQueryResults().

896 {
897  bool success = true;
898 
899  if (PQntuples(result) < 1)
900  {
901  pg_log_error("no rows returned for \\gset");
902  success = false;
903  }
904  else if (PQntuples(result) > 1)
905  {
906  pg_log_error("more than one row returned for \\gset");
907  success = false;
908  }
909  else
910  {
911  int i;
912 
913  for (i = 0; i < PQnfields(result); i++)
914  {
915  char *colname = PQfname(result, i);
916  char *varname;
917  char *value;
918 
919  /* concatenate prefix and column name */
920  varname = psprintf("%s%s", pset.gset_prefix, colname);
921 
922  if (!PQgetisnull(result, 0, i))
923  value = PQgetvalue(result, 0, i);
924  else
925  {
926  /* for NULL value, unset rather than set the variable */
927  value = NULL;
928  }
929 
930  if (!SetVariable(pset.vars, varname, value))
931  {
932  free(varname);
933  success = false;
934  break;
935  }
936 
937  free(varname);
938  }
939  }
940 
941  return success;
942 }
char * gset_prefix
Definition: settings.h:96
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2777
PsqlSettings pset
Definition: startup.c:31
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2855
#define pg_log_error(...)
Definition: logging.h:79
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
static struct @145 value
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define free(a)
Definition: header.h:65
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
int i
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3188
static bool success
Definition: initdb.c:163
VariableSpace vars
Definition: settings.h:118

◆ uri_prefix_length()

static int uri_prefix_length ( const char *  connstr)
static

Definition at line 2415 of file common.c.

References short_uri_designator, and uri_designator.

Referenced by recognized_connection_string().

2416 {
2417  /* The connection URI must start with either of the following designators: */
2418  static const char uri_designator[] = "postgresql://";
2419  static const char short_uri_designator[] = "postgres://";
2420 
2421  if (strncmp(connstr, uri_designator,
2422  sizeof(uri_designator) - 1) == 0)
2423  return sizeof(uri_designator) - 1;
2424 
2425  if (strncmp(connstr, short_uri_designator,
2426  sizeof(short_uri_designator) - 1) == 0)
2427  return sizeof(short_uri_designator) - 1;
2428 
2429  return 0;
2430 }
static const char short_uri_designator[]
Definition: fe-connect.c:379
static const char uri_designator[]
Definition: fe-connect.c:378
static char * connstr
Definition: pg_dumpall.c:61

Variable Documentation

◆ cancelConn

PGcancel* volatile cancelConn = NULL
static

Definition at line 255 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 253 of file common.c.

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