PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 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 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

#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 288 of file common.c.

Referenced by handle_sigint().

Function Documentation

static bool AcceptResult ( const PGresult result)
static

Definition at line 505 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 ExecQueryUsingCursor(), ProcessResult(), PSQLexec(), and PSQLexecWatch().

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

Definition at line 406 of file common.c.

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

Referenced by AcceptResult(), and ProcessResult().

407 {
408  bool OK;
409 
410  OK = ConnectionUp();
411  if (!OK)
412  {
414  {
415  psql_error("connection to server was lost\n");
416  exit(EXIT_BADCONN);
417  }
418 
419  psql_error("The connection to the server was lost. Attempting reset: ");
420  PQreset(pset.db);
421  OK = ConnectionUp();
422  if (!OK)
423  {
424  psql_error("Failed.\n");
425  PQfinish(pset.db);
426  pset.db = NULL;
427  ResetCancelConn();
428  UnsyncVariables();
429  }
430  else
431  psql_error("Succeeded.\n");
432  }
433 
434  return OK;
435 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3491
static bool ConnectionUp(void)
Definition: common.c:388
void UnsyncVariables(void)
Definition: command.c:3354
#define EXIT_BADCONN
Definition: settings.h:154
bool cur_cmd_interactive
Definition: settings.h:105
void psql_error(const char *fmt,...)
Definition: common.c:220
#define NULL
Definition: c.h:229
void ResetCancelConn(void)
Definition: common.c:475
void PQreset(PGconn *conn)
Definition: fe-connect.c:3505
static void ClearOrSaveResult ( PGresult result)
static

Definition at line 557 of file common.c.

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

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

558 {
559  if (result)
560  {
561  switch (PQresultStatus(result))
562  {
564  case PGRES_FATAL_ERROR:
568  break;
569 
570  default:
571  PQclear(result);
572  break;
573  }
574  }
575 }
PsqlSettings pset
Definition: startup.c:33
return result
Definition: formatting.c:1618
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
PGresult * last_error_result
Definition: settings.h:89
void PQclear(PGresult *res)
Definition: fe-exec.c:650
static bool command_no_begin ( const char *  query)
static

Definition at line 1796 of file common.c.

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

Referenced by SendQuery().

1797 {
1798  int wordlen;
1799 
1800  /*
1801  * First we must advance over any whitespace and comments.
1802  */
1803  query = skip_white_space(query);
1804 
1805  /*
1806  * Check word length (since "beginx" is not "begin").
1807  */
1808  wordlen = 0;
1809  while (isalpha((unsigned char) query[wordlen]))
1810  wordlen += PQmblen(&query[wordlen], pset.encoding);
1811 
1812  /*
1813  * Transaction control commands. These should include every keyword that
1814  * gives rise to a TransactionStmt in the backend grammar, except for the
1815  * savepoint-related commands.
1816  *
1817  * (We assume that START must be START TRANSACTION, since there is
1818  * presently no other "START foo" command.)
1819  */
1820  if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
1821  return true;
1822  if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
1823  return true;
1824  if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
1825  return true;
1826  if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
1827  return true;
1828  if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
1829  return true;
1830  if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
1831  return true;
1832  if (wordlen == 7 && pg_strncasecmp(query, "prepare", 7) == 0)
1833  {
1834  /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
1835  query += wordlen;
1836 
1837  query = skip_white_space(query);
1838 
1839  wordlen = 0;
1840  while (isalpha((unsigned char) query[wordlen]))
1841  wordlen += PQmblen(&query[wordlen], pset.encoding);
1842 
1843  if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0)
1844  return true;
1845  return false;
1846  }
1847 
1848  /*
1849  * Commands not allowed within transactions. The statements checked for
1850  * here should be exactly those that call PreventTransactionChain() in the
1851  * backend.
1852  */
1853  if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
1854  return true;
1855  if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
1856  {
1857  /* CLUSTER with any arguments is allowed in transactions */
1858  query += wordlen;
1859 
1860  query = skip_white_space(query);
1861 
1862  if (isalpha((unsigned char) query[0]))
1863  return false; /* has additional words */
1864  return true; /* it's CLUSTER without arguments */
1865  }
1866 
1867  if (wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0)
1868  {
1869  query += wordlen;
1870 
1871  query = skip_white_space(query);
1872 
1873  wordlen = 0;
1874  while (isalpha((unsigned char) query[wordlen]))
1875  wordlen += PQmblen(&query[wordlen], pset.encoding);
1876 
1877  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
1878  return true;
1879  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
1880  return true;
1881 
1882  /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
1883  if (wordlen == 6 && pg_strncasecmp(query, "unique", 6) == 0)
1884  {
1885  query += wordlen;
1886 
1887  query = skip_white_space(query);
1888 
1889  wordlen = 0;
1890  while (isalpha((unsigned char) query[wordlen]))
1891  wordlen += PQmblen(&query[wordlen], pset.encoding);
1892  }
1893 
1894  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
1895  {
1896  query += wordlen;
1897 
1898  query = skip_white_space(query);
1899 
1900  wordlen = 0;
1901  while (isalpha((unsigned char) query[wordlen]))
1902  wordlen += PQmblen(&query[wordlen], pset.encoding);
1903 
1904  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
1905  return true;
1906  }
1907 
1908  return false;
1909  }
1910 
1911  if (wordlen == 5 && pg_strncasecmp(query, "alter", 5) == 0)
1912  {
1913  query += wordlen;
1914 
1915  query = skip_white_space(query);
1916 
1917  wordlen = 0;
1918  while (isalpha((unsigned char) query[wordlen]))
1919  wordlen += PQmblen(&query[wordlen], pset.encoding);
1920 
1921  /* ALTER SYSTEM isn't allowed in xacts */
1922  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
1923  return true;
1924 
1925  return false;
1926  }
1927 
1928  /*
1929  * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
1930  * aren't really valid commands so we don't care much. The other four
1931  * possible matches are correct.
1932  */
1933  if ((wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
1934  (wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
1935  {
1936  query += wordlen;
1937 
1938  query = skip_white_space(query);
1939 
1940  wordlen = 0;
1941  while (isalpha((unsigned char) query[wordlen]))
1942  wordlen += PQmblen(&query[wordlen], pset.encoding);
1943 
1944  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
1945  return true;
1946  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
1947  return true;
1948  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
1949  return true;
1950 
1951  /* DROP INDEX CONCURRENTLY isn't allowed in xacts */
1952  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
1953  {
1954  query += wordlen;
1955 
1956  query = skip_white_space(query);
1957 
1958  wordlen = 0;
1959  while (isalpha((unsigned char) query[wordlen]))
1960  wordlen += PQmblen(&query[wordlen], pset.encoding);
1961 
1962  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
1963  return true;
1964 
1965  return false;
1966  }
1967 
1968  return false;
1969  }
1970 
1971  /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */
1972  if (wordlen == 7 && pg_strncasecmp(query, "discard", 7) == 0)
1973  {
1974  query += wordlen;
1975 
1976  query = skip_white_space(query);
1977 
1978  wordlen = 0;
1979  while (isalpha((unsigned char) query[wordlen]))
1980  wordlen += PQmblen(&query[wordlen], pset.encoding);
1981 
1982  if (wordlen == 3 && pg_strncasecmp(query, "all", 3) == 0)
1983  return true;
1984  return false;
1985  }
1986 
1987  return false;
1988 }
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:1184
static const char * skip_white_space(const char *query)
Definition: common.c:1732
static bool ConnectionUp ( void  )
static

Definition at line 388 of file common.c.

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

Referenced by CheckConnection(), and SendQuery().

389 {
390  return PQstatus(pset.db) != CONNECTION_BAD;
391 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:5881
static bool ExecQueryTuples ( const PGresult result)
static

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

912 {
913  bool success = true;
914  int nrows = PQntuples(result);
915  int ncolumns = PQnfields(result);
916  int r,
917  c;
918 
919  /*
920  * We must turn off gexec_flag to avoid infinite recursion. Note that
921  * this allows ExecQueryUsingCursor to be applied to the individual query
922  * results. SendQuery prevents it from being applied when fetching the
923  * queries-to-execute, because it can't handle recursion either.
924  */
925  pset.gexec_flag = false;
926 
927  for (r = 0; r < nrows; r++)
928  {
929  for (c = 0; c < ncolumns; c++)
930  {
931  if (!PQgetisnull(result, r, c))
932  {
933  const char *query = PQgetvalue(result, r, c);
934 
935  /* Abandon execution if cancel_pressed */
936  if (cancel_pressed)
937  goto loop_exit;
938 
939  /*
940  * ECHO_ALL mode should echo these queries, but SendQuery
941  * assumes that MainLoop did that, so we have to do it here.
942  */
944  {
945  puts(query);
946  fflush(stdout);
947  }
948 
949  if (!SendQuery(query))
950  {
951  /* Error - abandon execution if ON_ERROR_STOP */
952  success = false;
953  if (pset.on_error_stop)
954  goto loop_exit;
955  }
956  }
957  }
958  }
959 
960 loop_exit:
961 
962  /*
963  * Restore state. We know gexec_flag was on, else we'd not be here. (We
964  * also know it'll get turned off at end of command, but that's not ours
965  * to do here.)
966  */
967  pset.gexec_flag = true;
968 
969  /* Return true if all queries were successful */
970  return success;
971 }
PSQL_ECHO echo
Definition: settings.h:131
bool singlestep
Definition: settings.h:127
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2681
PsqlSettings pset
Definition: startup.c:33
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
bool gexec_flag
Definition: settings.h:96
bool on_error_stop
Definition: settings.h:124
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
volatile bool cancel_pressed
Definition: print.c:46
static bool success
Definition: pg_basebackup.c:96
char * c
bool SendQuery(const char *query)
Definition: common.c:1230
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3092
static bool ExecQueryUsingCursor ( const char *  query,
double *  elapsed_msec 
)
static

Definition at line 1496 of file common.c.

References AcceptResult(), appendPQExpBuffer(), Assert, before(), buf, cancel_pressed, cleanup(), ClearOrSaveResult(), ClosePager(), PQExpBufferData::data, _psqlSettings::db, disable_sigpipe_trap(), _psqlSettings::fetch_count, _psqlSettings::gfname, _psqlSettings::gset_prefix, initPQExpBuffer(), INSTR_TIME_GET_MILLISEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SUBTRACT, _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(), snprintf(), printTableOpt::start_table, printTableOpt::stop_table, StoreQueryTuple(), termPQExpBuffer(), _psqlSettings::timing, and printQueryOpt::topt.

Referenced by SendQuery().

1497 {
1498  bool OK = true;
1499  PGresult *results;
1501  printQueryOpt my_popt = pset.popt;
1502  FILE *fout;
1503  bool is_pipe;
1504  bool is_pager = false;
1505  bool started_txn = false;
1506  int ntuples;
1507  int fetch_count;
1508  char fetch_cmd[64];
1510  after;
1511  int flush_error;
1512 
1513  *elapsed_msec = 0;
1514 
1515  /* initialize print options for partial table output */
1516  my_popt.topt.start_table = true;
1517  my_popt.topt.stop_table = false;
1518  my_popt.topt.prior_records = 0;
1519 
1520  if (pset.timing)
1521  INSTR_TIME_SET_CURRENT(before);
1522 
1523  /* if we're not in a transaction, start one */
1525  {
1526  results = PQexec(pset.db, "BEGIN");
1527  OK = AcceptResult(results) &&
1528  (PQresultStatus(results) == PGRES_COMMAND_OK);
1529  ClearOrSaveResult(results);
1530  if (!OK)
1531  return false;
1532  started_txn = true;
1533  }
1534 
1535  /* Send DECLARE CURSOR */
1536  initPQExpBuffer(&buf);
1537  appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1538  query);
1539 
1540  results = PQexec(pset.db, buf.data);
1541  OK = AcceptResult(results) &&
1542  (PQresultStatus(results) == PGRES_COMMAND_OK);
1543  ClearOrSaveResult(results);
1544  termPQExpBuffer(&buf);
1545  if (!OK)
1546  goto cleanup;
1547 
1548  if (pset.timing)
1549  {
1550  INSTR_TIME_SET_CURRENT(after);
1551  INSTR_TIME_SUBTRACT(after, before);
1552  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1553  }
1554 
1555  /*
1556  * In \gset mode, we force the fetch count to be 2, so that we will throw
1557  * the appropriate error if the query returns more than one row.
1558  */
1559  if (pset.gset_prefix)
1560  fetch_count = 2;
1561  else
1562  fetch_count = pset.fetch_count;
1563 
1564  snprintf(fetch_cmd, sizeof(fetch_cmd),
1565  "FETCH FORWARD %d FROM _psql_cursor",
1566  fetch_count);
1567 
1568  /* prepare to write output to \g argument, if any */
1569  if (pset.gfname)
1570  {
1571  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
1572  {
1573  OK = false;
1574  goto cleanup;
1575  }
1576  if (is_pipe)
1578  }
1579  else
1580  {
1581  fout = pset.queryFout;
1582  is_pipe = false; /* doesn't matter */
1583  }
1584 
1585  /* clear any pre-existing error indication on the output stream */
1586  clearerr(fout);
1587 
1588  for (;;)
1589  {
1590  if (pset.timing)
1591  INSTR_TIME_SET_CURRENT(before);
1592 
1593  /* get fetch_count tuples at a time */
1594  results = PQexec(pset.db, fetch_cmd);
1595 
1596  if (pset.timing)
1597  {
1598  INSTR_TIME_SET_CURRENT(after);
1599  INSTR_TIME_SUBTRACT(after, before);
1600  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1601  }
1602 
1603  if (PQresultStatus(results) != PGRES_TUPLES_OK)
1604  {
1605  /* shut down pager before printing error message */
1606  if (is_pager)
1607  {
1608  ClosePager(fout);
1609  is_pager = false;
1610  }
1611 
1612  OK = AcceptResult(results);
1613  Assert(!OK);
1614  ClearOrSaveResult(results);
1615  break;
1616  }
1617 
1618  if (pset.gset_prefix)
1619  {
1620  /* StoreQueryTuple will complain if not exactly one row */
1621  OK = StoreQueryTuple(results);
1622  ClearOrSaveResult(results);
1623  break;
1624  }
1625 
1626  /* Note we do not deal with \gexec or \crosstabview modes here */
1627 
1628  ntuples = PQntuples(results);
1629 
1630  if (ntuples < fetch_count)
1631  {
1632  /* this is the last result set, so allow footer decoration */
1633  my_popt.topt.stop_table = true;
1634  }
1635  else if (fout == stdout && !is_pager)
1636  {
1637  /*
1638  * If query requires multiple result sets, hack to ensure that
1639  * only one pager instance is used for the whole mess
1640  */
1641  fout = PageOutput(INT_MAX, &(my_popt.topt));
1642  is_pager = true;
1643  }
1644 
1645  printQuery(results, &my_popt, fout, is_pager, pset.logfile);
1646 
1647  ClearOrSaveResult(results);
1648 
1649  /* after the first result set, disallow header decoration */
1650  my_popt.topt.start_table = false;
1651  my_popt.topt.prior_records += ntuples;
1652 
1653  /*
1654  * Make sure to flush the output stream, so intermediate results are
1655  * visible to the client immediately. We check the results because if
1656  * the pager dies/exits/etc, there's no sense throwing more data at
1657  * it.
1658  */
1659  flush_error = fflush(fout);
1660 
1661  /*
1662  * Check if we are at the end, if a cancel was pressed, or if there
1663  * were any errors either trying to flush out the results, or more
1664  * generally on the output stream at all. If we hit any errors
1665  * writing things to the stream, we presume $PAGER has disappeared and
1666  * stop bothering to pull down more data.
1667  */
1668  if (ntuples < fetch_count || cancel_pressed || flush_error ||
1669  ferror(fout))
1670  break;
1671  }
1672 
1673  if (pset.gfname)
1674  {
1675  /* close \g argument file/pipe */
1676  if (is_pipe)
1677  {
1678  pclose(fout);
1680  }
1681  else
1682  fclose(fout);
1683  }
1684  else if (is_pager)
1685  {
1686  /* close transient pager */
1687  ClosePager(fout);
1688  }
1689 
1690 cleanup:
1691  if (pset.timing)
1692  INSTR_TIME_SET_CURRENT(before);
1693 
1694  /*
1695  * We try to close the cursor on either success or failure, but on failure
1696  * ignore the result (it's probably just a bleat about being in an aborted
1697  * transaction)
1698  */
1699  results = PQexec(pset.db, "CLOSE _psql_cursor");
1700  if (OK)
1701  {
1702  OK = AcceptResult(results) &&
1703  (PQresultStatus(results) == PGRES_COMMAND_OK);
1704  ClearOrSaveResult(results);
1705  }
1706  else
1707  PQclear(results);
1708 
1709  if (started_txn)
1710  {
1711  results = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK");
1712  OK &= AcceptResult(results) &&
1713  (PQresultStatus(results) == PGRES_COMMAND_OK);
1714  ClearOrSaveResult(results);
1715  }
1716 
1717  if (pset.timing)
1718  {
1719  INSTR_TIME_SET_CURRENT(after);
1720  INSTR_TIME_SUBTRACT(after, before);
1721  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1722  }
1723 
1724  return OK;
1725 }
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:557
void disable_sigpipe_trap(void)
Definition: print.c:2801
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void ClosePager(FILE *pagerpipe)
Definition: print.c:2900
#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:2673
unsigned long prior_records
Definition: print.h:111
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
static bool AcceptResult(const PGresult *result)
Definition: common.c:505
volatile bool cancel_pressed
Definition: print.c:46
static int before(chr x, chr y)
Definition: regc_locale.c:496
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:66
int fetch_count
Definition: settings.h:128
void restore_sigpipe_trap(void)
Definition: print.c:2824
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:5889
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:49
char * gfname
Definition: settings.h:93
static void cleanup(void)
Definition: bootstrap.c:855
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
bool stop_table
Definition: print.h:109
#define Assert(condition)
Definition: c.h:675
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:153
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:854
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
void expand_tilde ( char **  filename)

Definition at line 2103 of file common.c.

References filename, fn(), free, get_home_path(), MAXPGPATH, NULL, 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().

2104 {
2105  if (!filename || !(*filename))
2106  return;
2107 
2108  /*
2109  * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2110  * for short versions of long file names, though the tilde is usually
2111  * toward the end, not at the beginning.
2112  */
2113 #ifndef WIN32
2114 
2115  /* try tilde expansion */
2116  if (**filename == '~')
2117  {
2118  char *fn;
2119  char oldp,
2120  *p;
2121  struct passwd *pw;
2122  char home[MAXPGPATH];
2123 
2124  fn = *filename;
2125  *home = '\0';
2126 
2127  p = fn + 1;
2128  while (*p != '/' && *p != '\0')
2129  p++;
2130 
2131  oldp = *p;
2132  *p = '\0';
2133 
2134  if (*(fn + 1) == '\0')
2135  get_home_path(home); /* ~ or ~/ only */
2136  else if ((pw = getpwnam(fn + 1)) != NULL)
2137  strlcpy(home, pw->pw_dir, sizeof(home)); /* ~user */
2138 
2139  *p = oldp;
2140  if (strlen(home) != 0)
2141  {
2142  char *newfn;
2143 
2144  newfn = psprintf("%s%s", home, p);
2145  free(fn);
2146  *filename = newfn;
2147  }
2148  }
2149 #endif
2150 
2151  return;
2152 }
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
#define NULL
Definition: c.h:229
static char * filename
Definition: pg_dumpall.c:87
bool get_home_path(char *ret_path)
Definition: path.c:807
static void handle_sigint ( SIGNAL_ARGS  )
static

Definition at line 300 of file common.c.

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

Referenced by setup_cancel_handler().

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

Definition at line 1995 of file common.c.

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

Referenced by SendQuery().

1996 {
1997  int wordlen;
1998 
1999  /*
2000  * First advance over any whitespace, comments and left parentheses.
2001  */
2002  for (;;)
2003  {
2004  query = skip_white_space(query);
2005  if (query[0] == '(')
2006  query++;
2007  else
2008  break;
2009  }
2010 
2011  /*
2012  * Check word length (since "selectx" is not "select").
2013  */
2014  wordlen = 0;
2015  while (isalpha((unsigned char) query[wordlen]))
2016  wordlen += PQmblen(&query[wordlen], pset.encoding);
2017 
2018  if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
2019  return true;
2020 
2021  if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
2022  return true;
2023 
2024  return false;
2025 }
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:1184
static const char * skip_white_space(const char *query)
Definition: common.c:1732
bool is_superuser ( void  )

Definition at line 2035 of file common.c.

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

2036 {
2037  const char *val;
2038 
2039  if (!pset.db)
2040  return false;
2041 
2042  val = PQparameterStatus(pset.db, "is_superuser");
2043 
2044  if (val && strcmp(val, "on") == 0)
2045  return true;
2046 
2047  return false;
2048 }
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:5899
long val
Definition: informix.c:689
void NoticeProcessor ( void *  arg,
const char *  message 
)

Definition at line 241 of file common.c.

References psql_error().

Referenced by do_connect(), and main().

242 {
243  (void) arg; /* not used */
244  psql_error("%s", message);
245 }
void psql_error(const char *fmt,...)
Definition: common.c:220
void * arg
bool openQueryOutputFile ( const char *  fname,
FILE **  fout,
bool is_pipe 
)

Definition at line 49 of file common.c.

References NULL, psql_error(), and strerror().

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

Definition at line 787 of file common.c.

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

Referenced by SendQuery().

788 {
789  PGnotify *notify;
790 
791  while ((notify = PQnotifies(pset.db)))
792  {
793  /* for backward compatibility, only show payload if nonempty */
794  if (notify->extra[0])
795  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
796  notify->relname, notify->extra, notify->be_pid);
797  else
798  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
799  notify->relname, notify->be_pid);
800  fflush(pset.queryFout);
801  PQfreemem(notify);
802  }
803 }
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:2193
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:3200
static bool PrintQueryResults ( PGresult results)
static

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

1156 {
1157  bool success;
1158  const char *cmdstatus;
1159 
1160  if (!results)
1161  return false;
1162 
1163  switch (PQresultStatus(results))
1164  {
1165  case PGRES_TUPLES_OK:
1166  /* store or execute or print the data ... */
1167  if (pset.gset_prefix)
1168  success = StoreQueryTuple(results);
1169  else if (pset.gexec_flag)
1170  success = ExecQueryTuples(results);
1171  else if (pset.crosstab_flag)
1172  success = PrintResultsInCrosstab(results);
1173  else
1174  success = PrintQueryTuples(results);
1175  /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
1176  cmdstatus = PQcmdStatus(results);
1177  if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
1178  strncmp(cmdstatus, "UPDATE", 6) == 0 ||
1179  strncmp(cmdstatus, "DELETE", 6) == 0)
1180  PrintQueryStatus(results);
1181  break;
1182 
1183  case PGRES_COMMAND_OK:
1184  PrintQueryStatus(results);
1185  success = true;
1186  break;
1187 
1188  case PGRES_EMPTY_QUERY:
1189  success = true;
1190  break;
1191 
1192  case PGRES_COPY_OUT:
1193  case PGRES_COPY_IN:
1194  /* nothing to do here */
1195  success = true;
1196  break;
1197 
1198  case PGRES_BAD_RESPONSE:
1199  case PGRES_NONFATAL_ERROR:
1200  case PGRES_FATAL_ERROR:
1201  success = false;
1202  break;
1203 
1204  default:
1205  success = false;
1206  psql_error("unexpected PQresultStatus: %d\n",
1207  PQresultStatus(results));
1208  break;
1209  }
1210 
1211  fflush(pset.queryFout);
1212 
1213  return success;
1214 }
static void PrintQueryStatus(PGresult *results)
Definition: common.c:1123
char * gset_prefix
Definition: settings.h:95
PsqlSettings pset
Definition: startup.c:33
static bool ExecQueryTuples(const PGresult *result)
Definition: common.c:911
static bool PrintQueryTuples(const PGresult *results)
Definition: common.c:812
bool gexec_flag
Definition: settings.h:96
FILE * queryFout
Definition: settings.h:84
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
static bool success
Definition: pg_basebackup.c:96
bool PrintResultsInCrosstab(const PGresult *res)
Definition: crosstabview.c:103
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2944
void psql_error(const char *fmt,...)
Definition: common.c:220
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:854
bool crosstab_flag
Definition: settings.h:97
static void PrintQueryStatus ( PGresult results)
static

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

1124 {
1125  char buf[16];
1126 
1127  if (!pset.quiet)
1128  {
1129  if (pset.popt.topt.format == PRINT_HTML)
1130  {
1131  fputs("<p>", pset.queryFout);
1133  fputs("</p>\n", pset.queryFout);
1134  }
1135  else
1136  fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
1137  }
1138 
1139  if (pset.logfile)
1140  fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
1141 
1142  snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
1143  SetVariable(pset.vars, "LASTOID", buf);
1144 }
PsqlSettings pset
Definition: startup.c:33
Oid PQoidValue(const PGresult *res)
Definition: fe-exec.c:2985
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:66
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2944
FILE * logfile
Definition: settings.h:114
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:116
static bool PrintQueryTuples ( const PGresult results)
static

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

813 {
814  printQueryOpt my_popt = pset.popt;
815 
816  /* one-shot expanded output requested via \gx */
817  if (pset.g_expanded)
818  my_popt.topt.expanded = 1;
819 
820  /* write output to \g argument, if any */
821  if (pset.gfname)
822  {
823  FILE *fout;
824  bool is_pipe;
825 
826  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
827  return false;
828  if (is_pipe)
830 
831  printQuery(results, &my_popt, fout, false, pset.logfile);
832 
833  if (is_pipe)
834  {
835  pclose(fout);
837  }
838  else
839  fclose(fout);
840  }
841  else
842  printQuery(results, &my_popt, pset.queryFout, false, pset.logfile);
843 
844  return true;
845 }
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:49
char * gfname
Definition: settings.h:93
FILE * logfile
Definition: settings.h:114
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
static void PrintTiming ( double  elapsed_msec)
static

Definition at line 583 of file common.c.

References _, and days.

Referenced by PSQLexecWatch(), and SendQuery().

584 {
585  double seconds;
586  double minutes;
587  double hours;
588  double days;
589 
590  if (elapsed_msec < 1000.0)
591  {
592  /* This is the traditional (pre-v10) output format */
593  printf(_("Time: %.3f ms\n"), elapsed_msec);
594  return;
595  }
596 
597  /*
598  * Note: we could print just seconds, in a format like %06.3f, when the
599  * total is less than 1min. But that's hard to interpret unless we tack
600  * on "s" or otherwise annotate it. Forcing the display to include
601  * minutes seems like a better solution.
602  */
603  seconds = elapsed_msec / 1000.0;
604  minutes = floor(seconds / 60.0);
605  seconds -= 60.0 * minutes;
606  if (minutes < 60.0)
607  {
608  printf(_("Time: %.3f ms (%02d:%06.3f)\n"),
609  elapsed_msec, (int) minutes, seconds);
610  return;
611  }
612 
613  hours = floor(minutes / 60.0);
614  minutes -= 60.0 * hours;
615  if (hours < 24.0)
616  {
617  printf(_("Time: %.3f ms (%02d:%02d:%06.3f)\n"),
618  elapsed_msec, (int) hours, (int) minutes, seconds);
619  return;
620  }
621 
622  days = floor(hours / 24.0);
623  hours -= 24.0 * days;
624  printf(_("Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n"),
625  elapsed_msec, days, (int) hours, (int) minutes, seconds);
626 }
const char *const days[]
Definition: datetime.c:69
#define _(x)
Definition: elog.c:84
static bool ProcessResult ( PGresult **  results)
static

Definition at line 995 of file common.c.

References AcceptResult(), CheckConnection(), _psqlSettings::copyStream, _psqlSettings::cur_cmd_source, _psqlSettings::db, handleCopyIn(), handleCopyOut(), NULL, 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(), and success.

Referenced by SendQuery().

996 {
997  bool success = true;
998  bool first_cycle = true;
999 
1000  for (;;)
1001  {
1002  ExecStatusType result_status;
1003  bool is_copy;
1004  PGresult *next_result;
1005 
1006  if (!AcceptResult(*results))
1007  {
1008  /*
1009  * Failure at this point is always a server-side failure or a
1010  * failure to submit the command string. Either way, we're
1011  * finished with this command string.
1012  */
1013  success = false;
1014  break;
1015  }
1016 
1017  result_status = PQresultStatus(*results);
1018  switch (result_status)
1019  {
1020  case PGRES_EMPTY_QUERY:
1021  case PGRES_COMMAND_OK:
1022  case PGRES_TUPLES_OK:
1023  is_copy = false;
1024  break;
1025 
1026  case PGRES_COPY_OUT:
1027  case PGRES_COPY_IN:
1028  is_copy = true;
1029  break;
1030 
1031  default:
1032  /* AcceptResult() should have caught anything else. */
1033  is_copy = false;
1034  psql_error("unexpected PQresultStatus: %d\n", result_status);
1035  break;
1036  }
1037 
1038  if (is_copy)
1039  {
1040  /*
1041  * Marshal the COPY data. Either subroutine will get the
1042  * connection out of its COPY state, then call PQresultStatus()
1043  * once and report any error.
1044  *
1045  * If pset.copyStream is set, use that as data source/sink,
1046  * otherwise use queryFout or cur_cmd_source as appropriate.
1047  */
1048  FILE *copystream = pset.copyStream;
1049  PGresult *copy_result;
1050 
1051  SetCancelConn();
1052  if (result_status == PGRES_COPY_OUT)
1053  {
1054  if (!copystream)
1055  copystream = pset.queryFout;
1056  success = handleCopyOut(pset.db,
1057  copystream,
1058  &copy_result) && success;
1059 
1060  /*
1061  * Suppress status printing if the report would go to the same
1062  * place as the COPY data just went. Note this doesn't
1063  * prevent error reporting, since handleCopyOut did that.
1064  */
1065  if (copystream == pset.queryFout)
1066  {
1067  PQclear(copy_result);
1068  copy_result = NULL;
1069  }
1070  }
1071  else
1072  {
1073  if (!copystream)
1074  copystream = pset.cur_cmd_source;
1075  success = handleCopyIn(pset.db,
1076  copystream,
1077  PQbinaryTuples(*results),
1078  &copy_result) && success;
1079  }
1080  ResetCancelConn();
1081 
1082  /*
1083  * Replace the PGRES_COPY_OUT/IN result with COPY command's exit
1084  * status, or with NULL if we want to suppress printing anything.
1085  */
1086  PQclear(*results);
1087  *results = copy_result;
1088  }
1089  else if (first_cycle)
1090  {
1091  /* fast path: no COPY commands; PQexec visited all results */
1092  break;
1093  }
1094 
1095  /*
1096  * Check PQgetResult() again. In the typical case of a single-command
1097  * string, it will return NULL. Otherwise, we'll have other results
1098  * to process that may include other COPYs. We keep the last result.
1099  */
1100  next_result = PQgetResult(pset.db);
1101  if (!next_result)
1102  break;
1103 
1104  PQclear(*results);
1105  *results = next_result;
1106  first_cycle = false;
1107  }
1108 
1109  /* may need this to recover from conn loss during COPY */
1110  if (!first_cycle && !CheckConnection())
1111  return false;
1112 
1113  return success;
1114 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
FILE * queryFout
Definition: settings.h:84
static bool CheckConnection(void)
Definition: common.c:406
ExecStatusType
Definition: libpq-fe.h:82
int PQbinaryTuples(const PGresult *res)
Definition: fe-exec.c:2689
FILE * copyStream
Definition: settings.h:87
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
FILE * cur_cmd_source
Definition: settings.h:103
static bool AcceptResult(const PGresult *result)
Definition: common.c:505
static bool success
Definition: pg_basebackup.c:96
bool handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res)
Definition: copy.c:435
void SetCancelConn(void)
Definition: common.c:445
void psql_error(const char *fmt,...)
Definition: common.c:220
void PQclear(PGresult *res)
Definition: fe-exec.c:650
bool handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
Definition: copy.c:514
#define NULL
Definition: c.h:229
void ResetCancelConn(void)
Definition: common.c:475
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
void psql_error ( const char *  fmt,
  ... 
)

Definition at line 220 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(), 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(), exec_command_elif(), exec_command_else(), exec_command_encoding(), exec_command_endif(), exec_command_errverbose(), exec_command_ev(), exec_command_include(), exec_command_lo(), exec_command_password(), exec_command_prompt(), exec_command_setenv(), exec_command_sf(), exec_command_sv(), exec_command_unset(), exec_command_write(), get_create_object_cmd(), gets_fromFile(), handleCopyIn(), handleCopyOut(), HandleSlashCmds(), indexOfColumn(), listCollations(), listDefaultACLs(), listExtensionContents(), listExtensions(), listForeignDataWrappers(), listForeignServers(), listForeignTables(), listPublications(), 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().

221 {
222  va_list ap;
223 
224  fflush(stdout);
225  if (pset.queryFout && pset.queryFout != stdout)
226  fflush(pset.queryFout);
227 
228  if (pset.inputfile)
229  fprintf(stderr, "%s:%s:" UINT64_FORMAT ": ", pset.progname, pset.inputfile, pset.lineno);
230  va_start(ap, fmt);
231  vfprintf(stderr, _(fmt), ap);
232  va_end(ap);
233 }
PsqlSettings pset
Definition: startup.c:33
FILE * queryFout
Definition: settings.h:84
char * inputfile
Definition: settings.h:108
const char * progname
Definition: settings.h:107
uint64 lineno
Definition: settings.h:109
#define _(x)
Definition: elog.c:84
#define UINT64_FORMAT
Definition: c.h:316
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(), NULL, pg_strdup(), PQerrorMessage(), PQescapeIdentifier(), PQescapeLiteral(), PQfreemem(), PQUOTE_PLAIN, PQUOTE_SHELL_ARG, PQUOTE_SQL_IDENT, PQUOTE_SQL_LITERAL, pset, psql_error(), result, 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  psql_error("cannot escape without active connection\n");
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  psql_error("%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  psql_error("shell command argument contains a newline or carriage return: \"%s\"\n",
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:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5934
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
return result
Definition: formatting.c:1618
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3474
static char * buf
Definition: pg_test_fsync.c:66
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:220
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3468
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
static struct @121 value
void PQfreemem(void *ptr)
Definition: fe-exec.c:3200
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
VariableSpace vars
Definition: settings.h:116
PGresult* PSQLexec ( const char *  query)

Definition at line 642 of file common.c.

References _, AcceptResult(), ClearOrSaveResult(), _psqlSettings::db, _psqlSettings::echo_hidden, _psqlSettings::logfile, NULL, 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().

643 {
644  PGresult *res;
645 
646  if (!pset.db)
647  {
648  psql_error("You are currently not connected to a database.\n");
649  return NULL;
650  }
651 
653  {
654  printf(_("********* QUERY **********\n"
655  "%s\n"
656  "**************************\n\n"), query);
657  fflush(stdout);
658  if (pset.logfile)
659  {
660  fprintf(pset.logfile,
661  _("********* QUERY **********\n"
662  "%s\n"
663  "**************************\n\n"), query);
664  fflush(pset.logfile);
665  }
666 
668  return NULL;
669  }
670 
671  SetCancelConn();
672 
673  res = PQexec(pset.db, query);
674 
675  ResetCancelConn();
676 
677  if (!AcceptResult(res))
678  {
679  ClearOrSaveResult(res);
680  res = NULL;
681  }
682 
683  return res;
684 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:557
static bool AcceptResult(const PGresult *result)
Definition: common.c:505
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:132
void SetCancelConn(void)
Definition: common.c:445
void psql_error(const char *fmt,...)
Definition: common.c:220
FILE * logfile
Definition: settings.h:114
#define NULL
Definition: c.h:229
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
void ResetCancelConn(void)
Definition: common.c:475
#define _(x)
Definition: elog.c:84
int PSQLexecWatch ( const char *  query,
const printQueryOpt opt 
)

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

698 {
699  PGresult *res;
700  double elapsed_msec = 0;
702  instr_time after;
703 
704  if (!pset.db)
705  {
706  psql_error("You are currently not connected to a database.\n");
707  return 0;
708  }
709 
710  SetCancelConn();
711 
712  if (pset.timing)
713  INSTR_TIME_SET_CURRENT(before);
714 
715  res = PQexec(pset.db, query);
716 
717  ResetCancelConn();
718 
719  if (!AcceptResult(res))
720  {
721  ClearOrSaveResult(res);
722  return 0;
723  }
724 
725  if (pset.timing)
726  {
727  INSTR_TIME_SET_CURRENT(after);
728  INSTR_TIME_SUBTRACT(after, before);
729  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
730  }
731 
732  /*
733  * If SIGINT is sent while the query is processing, the interrupt will be
734  * consumed. The user's intention, though, is to cancel the entire watch
735  * process, so detect a sent cancellation request and exit in this case.
736  */
737  if (cancel_pressed)
738  {
739  PQclear(res);
740  return 0;
741  }
742 
743  switch (PQresultStatus(res))
744  {
745  case PGRES_TUPLES_OK:
746  printQuery(res, opt, pset.queryFout, false, pset.logfile);
747  break;
748 
749  case PGRES_COMMAND_OK:
750  fprintf(pset.queryFout, "%s\n%s\n\n", opt->title, PQcmdStatus(res));
751  break;
752 
753  case PGRES_EMPTY_QUERY:
754  psql_error(_("\\watch cannot be used with an empty query\n"));
755  PQclear(res);
756  return -1;
757 
758  case PGRES_COPY_OUT:
759  case PGRES_COPY_IN:
760  case PGRES_COPY_BOTH:
761  psql_error(_("\\watch cannot be used with COPY\n"));
762  PQclear(res);
763  return -1;
764 
765  default:
766  psql_error(_("unexpected result status for \\watch\n"));
767  PQclear(res);
768  return -1;
769  }
770 
771  PQclear(res);
772 
773  fflush(pset.queryFout);
774 
775  /* Possible microtiming output */
776  if (pset.timing)
777  PrintTiming(elapsed_msec);
778 
779  return 1;
780 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:557
#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:583
FILE * queryFout
Definition: settings.h:84
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
static bool AcceptResult(const PGresult *result)
Definition: common.c:505
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:445
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2944
void psql_error(const char *fmt,...)
Definition: common.c:220
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:153
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
void ResetCancelConn(void)
Definition: common.c:475
#define _(x)
Definition: elog.c:84
static bool recognized_connection_string ( const char *  connstr)

Definition at line 2190 of file common.c.

References NULL, and uri_prefix_length().

Referenced by do_connect().

2191 {
2192  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
2193 }
static int uri_prefix_length(const char *connstr)
Definition: common.c:2163
#define NULL
Definition: c.h:229
static char * connstr
Definition: pg_dumpall.c:64
void ResetCancelConn ( void  )

Definition at line 475 of file common.c.

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

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

Definition at line 1230 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, _psqlSettings::echo, _psqlSettings::encoding, printTableOpt::encoding, ExecQueryUsingCursor(), _psqlSettings::fetch_count, formatPGVersionNumber(), free, _psqlSettings::g_expanded, _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, NULL, _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().

1231 {
1232  PGresult *results;
1233  PGTransactionStatusType transaction_status;
1234  double elapsed_msec = 0;
1235  bool OK = false;
1236  int i;
1237  bool on_error_rollback_savepoint = false;
1238  static bool on_error_rollback_warning = false;
1239 
1240  if (!pset.db)
1241  {
1242  psql_error("You are currently not connected to a database.\n");
1243  goto sendquery_cleanup;
1244  }
1245 
1246  if (pset.singlestep)
1247  {
1248  char buf[3];
1249 
1250  fflush(stderr);
1251  printf(_("***(Single step mode: verify command)*******************************************\n"
1252  "%s\n"
1253  "***(press return to proceed or enter x and return to cancel)********************\n"),
1254  query);
1255  fflush(stdout);
1256  if (fgets(buf, sizeof(buf), stdin) != NULL)
1257  if (buf[0] == 'x')
1258  goto sendquery_cleanup;
1259  if (cancel_pressed)
1260  goto sendquery_cleanup;
1261  }
1262  else if (pset.echo == PSQL_ECHO_QUERIES)
1263  {
1264  puts(query);
1265  fflush(stdout);
1266  }
1267 
1268  if (pset.logfile)
1269  {
1270  fprintf(pset.logfile,
1271  _("********* QUERY **********\n"
1272  "%s\n"
1273  "**************************\n\n"), query);
1274  fflush(pset.logfile);
1275  }
1276 
1277  SetCancelConn();
1278 
1279  transaction_status = PQtransactionStatus(pset.db);
1280 
1281  if (transaction_status == PQTRANS_IDLE &&
1282  !pset.autocommit &&
1283  !command_no_begin(query))
1284  {
1285  results = PQexec(pset.db, "BEGIN");
1286  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1287  {
1288  psql_error("%s", PQerrorMessage(pset.db));
1289  ClearOrSaveResult(results);
1290  ResetCancelConn();
1291  goto sendquery_cleanup;
1292  }
1293  ClearOrSaveResult(results);
1294  transaction_status = PQtransactionStatus(pset.db);
1295  }
1296 
1297  if (transaction_status == PQTRANS_INTRANS &&
1301  {
1302  if (on_error_rollback_warning == false && pset.sversion < 80000)
1303  {
1304  char sverbuf[32];
1305 
1306  psql_error("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n",
1308  sverbuf, sizeof(sverbuf)));
1309  on_error_rollback_warning = true;
1310  }
1311  else
1312  {
1313  results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
1314  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1315  {
1316  psql_error("%s", PQerrorMessage(pset.db));
1317  ClearOrSaveResult(results);
1318  ResetCancelConn();
1319  goto sendquery_cleanup;
1320  }
1321  ClearOrSaveResult(results);
1322  on_error_rollback_savepoint = true;
1323  }
1324  }
1325 
1326  if (pset.fetch_count <= 0 || pset.gexec_flag ||
1328  {
1329  /* Default fetch-it-all-and-print mode */
1331  after;
1332 
1333  if (pset.timing)
1334  INSTR_TIME_SET_CURRENT(before);
1335 
1336  results = PQexec(pset.db, query);
1337 
1338  /* these operations are included in the timing result: */
1339  ResetCancelConn();
1340  OK = ProcessResult(&results);
1341 
1342  if (pset.timing)
1343  {
1344  INSTR_TIME_SET_CURRENT(after);
1345  INSTR_TIME_SUBTRACT(after, before);
1346  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1347  }
1348 
1349  /* but printing results isn't: */
1350  if (OK && results)
1351  OK = PrintQueryResults(results);
1352  }
1353  else
1354  {
1355  /* Fetch-in-segments mode */
1356  OK = ExecQueryUsingCursor(query, &elapsed_msec);
1357  ResetCancelConn();
1358  results = NULL; /* PQclear(NULL) does nothing */
1359  }
1360 
1361  if (!OK && pset.echo == PSQL_ECHO_ERRORS)
1362  psql_error("STATEMENT: %s\n", query);
1363 
1364  /* If we made a temporary savepoint, possibly release/rollback */
1365  if (on_error_rollback_savepoint)
1366  {
1367  const char *svptcmd = NULL;
1368 
1369  transaction_status = PQtransactionStatus(pset.db);
1370 
1371  switch (transaction_status)
1372  {
1373  case PQTRANS_INERROR:
1374  /* We always rollback on an error */
1375  svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
1376  break;
1377 
1378  case PQTRANS_IDLE:
1379  /* If they are no longer in a transaction, then do nothing */
1380  break;
1381 
1382  case PQTRANS_INTRANS:
1383 
1384  /*
1385  * Do nothing if they are messing with savepoints themselves:
1386  * If the user did RELEASE or ROLLBACK, our savepoint is gone.
1387  * If they issued a SAVEPOINT, releasing ours would remove
1388  * theirs.
1389  */
1390  if (results &&
1391  (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
1392  strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
1393  strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
1394  svptcmd = NULL;
1395  else
1396  svptcmd = "RELEASE pg_psql_temporary_savepoint";
1397  break;
1398 
1399  case PQTRANS_ACTIVE:
1400  case PQTRANS_UNKNOWN:
1401  default:
1402  OK = false;
1403  /* PQTRANS_UNKNOWN is expected given a broken connection. */
1404  if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp())
1405  psql_error("unexpected transaction status (%d)\n",
1406  transaction_status);
1407  break;
1408  }
1409 
1410  if (svptcmd)
1411  {
1412  PGresult *svptres;
1413 
1414  svptres = PQexec(pset.db, svptcmd);
1415  if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
1416  {
1417  psql_error("%s", PQerrorMessage(pset.db));
1418  ClearOrSaveResult(svptres);
1419  OK = false;
1420 
1421  PQclear(results);
1422  ResetCancelConn();
1423  goto sendquery_cleanup;
1424  }
1425  PQclear(svptres);
1426  }
1427  }
1428 
1429  ClearOrSaveResult(results);
1430 
1431  /* Possible microtiming output */
1432  if (pset.timing)
1433  PrintTiming(elapsed_msec);
1434 
1435  /* check for events that may occur during query execution */
1436 
1437  if (pset.encoding != PQclientEncoding(pset.db) &&
1438  PQclientEncoding(pset.db) >= 0)
1439  {
1440  /* track effects of SET CLIENT_ENCODING */
1443  SetVariable(pset.vars, "ENCODING",
1445  }
1446 
1448 
1449  /* perform cleanup that should occur after any attempted query */
1450 
1451 sendquery_cleanup:
1452 
1453  /* reset \g's output-to-filename trigger */
1454  if (pset.gfname)
1455  {
1456  free(pset.gfname);
1457  pset.gfname = NULL;
1458  }
1459 
1460  /* reset \gx's expanded-mode flag */
1461  pset.g_expanded = false;
1462 
1463  /* reset \gset trigger */
1464  if (pset.gset_prefix)
1465  {
1467  pset.gset_prefix = NULL;
1468  }
1469 
1470  /* reset \gexec trigger */
1471  pset.gexec_flag = false;
1472 
1473  /* reset \crosstabview trigger */
1474  pset.crosstab_flag = false;
1475  for (i = 0; i < lengthof(pset.ctv_args); i++)
1476  {
1477  pg_free(pset.ctv_args[i]);
1478  pset.ctv_args[i] = NULL;
1479  }
1480 
1481  return OK;
1482 }
PSQL_ECHO echo
Definition: settings.h:131
bool singlestep
Definition: settings.h:127
char * gset_prefix
Definition: settings.h:95
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1155
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5934
int encoding
Definition: print.h:118
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:557
#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:96
printTableOpt topt
Definition: print.h:165
static void PrintTiming(double elapsed_msec)
Definition: common.c:583
static bool ConnectionUp(void)
Definition: common.c:388
bool autocommit
Definition: settings.h:123
#define lengthof(array)
Definition: c.h:562
PSQL_ERROR_ROLLBACK on_error_rollback
Definition: settings.h:133
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:5994
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
volatile bool cancel_pressed
Definition: print.c:46
static void PrintNotifications(void)
Definition: common.c:787
char * ctv_args[4]
Definition: settings.h:98
static int before(chr x, chr y)
Definition: regc_locale.c:496
bool cur_cmd_interactive
Definition: settings.h:105
static bool is_select_command(const char *query)
Definition: common.c:1995
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:167
static char * buf
Definition: pg_test_fsync.c:66
int fetch_count
Definition: settings.h:128
static bool ProcessResult(PGresult **results)
Definition: common.c:995
bool g_expanded
Definition: settings.h:94
void SetCancelConn(void)
Definition: common.c:445
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1496
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:5889
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2944
void psql_error(const char *fmt,...)
Definition: common.c:220
char * gfname
Definition: settings.h:93
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#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
#define NULL
Definition: c.h:229
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:97
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
int encoding
Definition: settings.h:83
static bool command_no_begin(const char *query)
Definition: common.c:1796
void ResetCancelConn(void)
Definition: common.c:475
#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:116
const char* session_username ( void  )

Definition at line 2082 of file common.c.

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

Referenced by get_prompt().

2083 {
2084  const char *val;
2085 
2086  if (!pset.db)
2087  return NULL;
2088 
2089  val = PQparameterStatus(pset.db, "session_authorization");
2090  if (val)
2091  return val;
2092  else
2093  return PQuser(pset.db);
2094 }
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:5899
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:5810
#define NULL
Definition: c.h:229
long val
Definition: informix.c:689
void SetCancelConn ( void  )

Definition at line 445 of file common.c.

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

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

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

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

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: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:49
void setup_cancel_handler ( void  )

Definition at line 331 of file common.c.

332 {
333  pqsignal(SIGINT, handle_sigint);
334 }
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
static void handle_sigint(SIGNAL_ARGS)
Definition: common.c:300
static const char* skip_white_space ( const char *  query)
static

Definition at line 1732 of file common.c.

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

Referenced by command_no_begin(), and is_select_command().

1733 {
1734  int cnestlevel = 0; /* slash-star comment nest level */
1735 
1736  while (*query)
1737  {
1738  int mblen = PQmblen(query, pset.encoding);
1739 
1740  /*
1741  * Note: we assume the encoding is a superset of ASCII, so that for
1742  * example "query[0] == '/'" is meaningful. However, we do NOT assume
1743  * that the second and subsequent bytes of a multibyte character
1744  * couldn't look like ASCII characters; so it is critical to advance
1745  * by mblen, not 1, whenever we haven't exactly identified the
1746  * character we are skipping over.
1747  */
1748  if (isspace((unsigned char) *query))
1749  query += mblen;
1750  else if (query[0] == '/' && query[1] == '*')
1751  {
1752  cnestlevel++;
1753  query += 2;
1754  }
1755  else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
1756  {
1757  cnestlevel--;
1758  query += 2;
1759  }
1760  else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
1761  {
1762  query += 2;
1763 
1764  /*
1765  * We have to skip to end of line since any slash-star inside the
1766  * -- comment does NOT start a slash-star comment.
1767  */
1768  while (*query)
1769  {
1770  if (*query == '\n')
1771  {
1772  query++;
1773  break;
1774  }
1775  query += PQmblen(query, pset.encoding);
1776  }
1777  }
1778  else if (cnestlevel > 0)
1779  query += mblen;
1780  else
1781  break; /* found first token */
1782  }
1783 
1784  return query;
1785 }
PsqlSettings pset
Definition: startup.c:33
int encoding
Definition: settings.h:83
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1184
bool standard_strings ( void  )

Definition at line 2058 of file common.c.

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

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

2059 {
2060  const char *val;
2061 
2062  if (!pset.db)
2063  return false;
2064 
2065  val = PQparameterStatus(pset.db, "standard_conforming_strings");
2066 
2067  if (val && strcmp(val, "on") == 0)
2068  return true;
2069 
2070  return false;
2071 }
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:5899
long val
Definition: informix.c:689
static bool StoreQueryTuple ( const PGresult result)
static

Definition at line 854 of file common.c.

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

Referenced by ExecQueryUsingCursor(), and PrintQueryResults().

855 {
856  bool success = true;
857 
858  if (PQntuples(result) < 1)
859  {
860  psql_error("no rows returned for \\gset\n");
861  success = false;
862  }
863  else if (PQntuples(result) > 1)
864  {
865  psql_error("more than one row returned for \\gset\n");
866  success = false;
867  }
868  else
869  {
870  int i;
871 
872  for (i = 0; i < PQnfields(result); i++)
873  {
874  char *colname = PQfname(result, i);
875  char *varname;
876  char *value;
877 
878  /* concatenate prefix and column name */
879  varname = psprintf("%s%s", pset.gset_prefix, colname);
880 
881  if (!PQgetisnull(result, 0, i))
882  value = PQgetvalue(result, 0, i);
883  else
884  {
885  /* for NULL value, unset rather than set the variable */
886  value = NULL;
887  }
888 
889  if (!SetVariable(pset.vars, varname, value))
890  {
891  free(varname);
892  success = false;
893  break;
894  }
895 
896  free(varname);
897  }
898  }
899 
900  return success;
901 }
char * gset_prefix
Definition: settings.h:95
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2681
PsqlSettings pset
Definition: startup.c:33
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2759
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
static bool success
Definition: pg_basebackup.c:96
void psql_error(const char *fmt,...)
Definition: common.c:220
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
int i
static struct @121 value
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3092
VariableSpace vars
Definition: settings.h:116
static int uri_prefix_length ( const char *  connstr)
static

Definition at line 2163 of file common.c.

References short_uri_designator, and uri_designator.

Referenced by recognized_connection_string().

2164 {
2165  /* The connection URI must start with either of the following designators: */
2166  static const char uri_designator[] = "postgresql://";
2167  static const char short_uri_designator[] = "postgres://";
2168 
2169  if (strncmp(connstr, uri_designator,
2170  sizeof(uri_designator) - 1) == 0)
2171  return sizeof(uri_designator) - 1;
2172 
2173  if (strncmp(connstr, short_uri_designator,
2174  sizeof(short_uri_designator) - 1) == 0)
2175  return sizeof(short_uri_designator) - 1;
2176 
2177  return 0;
2178 }
static const char short_uri_designator[]
Definition: fe-connect.c:332
static const char uri_designator[]
Definition: fe-connect.c:331
static char * connstr
Definition: pg_dumpall.c:64

Variable Documentation

PGcancel* volatile cancelConn = NULL
static

Definition at line 277 of file common.c.

Referenced by ResetCancelConn(), and SetCancelConn().

volatile bool sigint_interrupt_enabled = false
sigjmp_buf sigint_interrupt_jmp

Definition at line 275 of file common.c.

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