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, bool escape, bool as_ident, 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:19

Definition at line 249 of file common.c.

Referenced by handle_sigint().

Function Documentation

static bool AcceptResult ( const PGresult result)
static

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

467 {
468  bool OK;
469 
470  if (!result)
471  OK = false;
472  else
473  switch (PQresultStatus(result))
474  {
475  case PGRES_COMMAND_OK:
476  case PGRES_TUPLES_OK:
477  case PGRES_EMPTY_QUERY:
478  case PGRES_COPY_IN:
479  case PGRES_COPY_OUT:
480  /* Fine, do nothing */
481  OK = true;
482  break;
483 
484  case PGRES_BAD_RESPONSE:
486  case PGRES_FATAL_ERROR:
487  OK = false;
488  break;
489 
490  default:
491  OK = false;
492  psql_error("unexpected PQresultStatus: %d\n",
493  PQresultStatus(result));
494  break;
495  }
496 
497  if (!OK)
498  {
499  const char *error = PQerrorMessage(pset.db);
500 
501  if (strlen(error))
502  psql_error("%s", error);
503 
504  CheckConnection();
505  }
506 
507  return OK;
508 }
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6011
PsqlSettings pset
Definition: startup.c:33
static void error(void)
Definition: sql-dyntest.c:147
static bool CheckConnection(void)
Definition: common.c:367
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
void psql_error(const char *fmt,...)
Definition: common.c:181
static bool CheckConnection ( void  )
static

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

368 {
369  bool OK;
370 
371  OK = ConnectionUp();
372  if (!OK)
373  {
375  {
376  psql_error("connection to server was lost\n");
377  exit(EXIT_BADCONN);
378  }
379 
380  psql_error("The connection to the server was lost. Attempting reset: ");
381  PQreset(pset.db);
382  OK = ConnectionUp();
383  if (!OK)
384  {
385  psql_error("Failed.\n");
386  PQfinish(pset.db);
387  pset.db = NULL;
388  ResetCancelConn();
389  UnsyncVariables();
390  }
391  else
392  psql_error("Succeeded.\n");
393  }
394 
395  return OK;
396 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3568
static bool ConnectionUp(void)
Definition: common.c:349
void UnsyncVariables(void)
Definition: command.c:2179
#define EXIT_BADCONN
Definition: settings.h:154
bool cur_cmd_interactive
Definition: settings.h:105
void psql_error(const char *fmt,...)
Definition: common.c:181
#define NULL
Definition: c.h:229
void ResetCancelConn(void)
Definition: common.c:436
void PQreset(PGconn *conn)
Definition: fe-connect.c:3582
static void ClearOrSaveResult ( PGresult result)
static

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

519 {
520  if (result)
521  {
522  switch (PQresultStatus(result))
523  {
525  case PGRES_FATAL_ERROR:
529  break;
530 
531  default:
532  PQclear(result);
533  break;
534  }
535  }
536 }
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 1757 of file common.c.

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

Referenced by SendQuery().

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

Definition at line 349 of file common.c.

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

Referenced by CheckConnection(), and SendQuery().

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

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

873 {
874  bool success = true;
875  int nrows = PQntuples(result);
876  int ncolumns = PQnfields(result);
877  int r,
878  c;
879 
880  /*
881  * We must turn off gexec_flag to avoid infinite recursion. Note that
882  * this allows ExecQueryUsingCursor to be applied to the individual query
883  * results. SendQuery prevents it from being applied when fetching the
884  * queries-to-execute, because it can't handle recursion either.
885  */
886  pset.gexec_flag = false;
887 
888  for (r = 0; r < nrows; r++)
889  {
890  for (c = 0; c < ncolumns; c++)
891  {
892  if (!PQgetisnull(result, r, c))
893  {
894  const char *query = PQgetvalue(result, r, c);
895 
896  /* Abandon execution if cancel_pressed */
897  if (cancel_pressed)
898  goto loop_exit;
899 
900  /*
901  * ECHO_ALL mode should echo these queries, but SendQuery
902  * assumes that MainLoop did that, so we have to do it here.
903  */
905  {
906  puts(query);
907  fflush(stdout);
908  }
909 
910  if (!SendQuery(query))
911  {
912  /* Error - abandon execution if ON_ERROR_STOP */
913  success = false;
914  if (pset.on_error_stop)
915  goto loop_exit;
916  }
917  }
918  }
919  }
920 
921 loop_exit:
922 
923  /*
924  * Restore state. We know gexec_flag was on, else we'd not be here. (We
925  * also know it'll get turned off at end of command, but that's not ours
926  * to do here.)
927  */
928  pset.gexec_flag = true;
929 
930  /* Return true if all queries were successful */
931  return success;
932 }
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:1191
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 1457 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().

1458 {
1459  bool OK = true;
1460  PGresult *results;
1462  printQueryOpt my_popt = pset.popt;
1463  FILE *fout;
1464  bool is_pipe;
1465  bool is_pager = false;
1466  bool started_txn = false;
1467  int ntuples;
1468  int fetch_count;
1469  char fetch_cmd[64];
1471  after;
1472  int flush_error;
1473 
1474  *elapsed_msec = 0;
1475 
1476  /* initialize print options for partial table output */
1477  my_popt.topt.start_table = true;
1478  my_popt.topt.stop_table = false;
1479  my_popt.topt.prior_records = 0;
1480 
1481  if (pset.timing)
1482  INSTR_TIME_SET_CURRENT(before);
1483 
1484  /* if we're not in a transaction, start one */
1486  {
1487  results = PQexec(pset.db, "BEGIN");
1488  OK = AcceptResult(results) &&
1489  (PQresultStatus(results) == PGRES_COMMAND_OK);
1490  ClearOrSaveResult(results);
1491  if (!OK)
1492  return false;
1493  started_txn = true;
1494  }
1495 
1496  /* Send DECLARE CURSOR */
1497  initPQExpBuffer(&buf);
1498  appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1499  query);
1500 
1501  results = PQexec(pset.db, buf.data);
1502  OK = AcceptResult(results) &&
1503  (PQresultStatus(results) == PGRES_COMMAND_OK);
1504  ClearOrSaveResult(results);
1505  termPQExpBuffer(&buf);
1506  if (!OK)
1507  goto cleanup;
1508 
1509  if (pset.timing)
1510  {
1511  INSTR_TIME_SET_CURRENT(after);
1512  INSTR_TIME_SUBTRACT(after, before);
1513  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1514  }
1515 
1516  /*
1517  * In \gset mode, we force the fetch count to be 2, so that we will throw
1518  * the appropriate error if the query returns more than one row.
1519  */
1520  if (pset.gset_prefix)
1521  fetch_count = 2;
1522  else
1523  fetch_count = pset.fetch_count;
1524 
1525  snprintf(fetch_cmd, sizeof(fetch_cmd),
1526  "FETCH FORWARD %d FROM _psql_cursor",
1527  fetch_count);
1528 
1529  /* prepare to write output to \g argument, if any */
1530  if (pset.gfname)
1531  {
1532  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
1533  {
1534  OK = false;
1535  goto cleanup;
1536  }
1537  if (is_pipe)
1539  }
1540  else
1541  {
1542  fout = pset.queryFout;
1543  is_pipe = false; /* doesn't matter */
1544  }
1545 
1546  /* clear any pre-existing error indication on the output stream */
1547  clearerr(fout);
1548 
1549  for (;;)
1550  {
1551  if (pset.timing)
1552  INSTR_TIME_SET_CURRENT(before);
1553 
1554  /* get fetch_count tuples at a time */
1555  results = PQexec(pset.db, fetch_cmd);
1556 
1557  if (pset.timing)
1558  {
1559  INSTR_TIME_SET_CURRENT(after);
1560  INSTR_TIME_SUBTRACT(after, before);
1561  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1562  }
1563 
1564  if (PQresultStatus(results) != PGRES_TUPLES_OK)
1565  {
1566  /* shut down pager before printing error message */
1567  if (is_pager)
1568  {
1569  ClosePager(fout);
1570  is_pager = false;
1571  }
1572 
1573  OK = AcceptResult(results);
1574  Assert(!OK);
1575  ClearOrSaveResult(results);
1576  break;
1577  }
1578 
1579  if (pset.gset_prefix)
1580  {
1581  /* StoreQueryTuple will complain if not exactly one row */
1582  OK = StoreQueryTuple(results);
1583  ClearOrSaveResult(results);
1584  break;
1585  }
1586 
1587  /* Note we do not deal with \gexec or \crosstabview modes here */
1588 
1589  ntuples = PQntuples(results);
1590 
1591  if (ntuples < fetch_count)
1592  {
1593  /* this is the last result set, so allow footer decoration */
1594  my_popt.topt.stop_table = true;
1595  }
1596  else if (fout == stdout && !is_pager)
1597  {
1598  /*
1599  * If query requires multiple result sets, hack to ensure that
1600  * only one pager instance is used for the whole mess
1601  */
1602  fout = PageOutput(INT_MAX, &(my_popt.topt));
1603  is_pager = true;
1604  }
1605 
1606  printQuery(results, &my_popt, fout, is_pager, pset.logfile);
1607 
1608  ClearOrSaveResult(results);
1609 
1610  /* after the first result set, disallow header decoration */
1611  my_popt.topt.start_table = false;
1612  my_popt.topt.prior_records += ntuples;
1613 
1614  /*
1615  * Make sure to flush the output stream, so intermediate results are
1616  * visible to the client immediately. We check the results because if
1617  * the pager dies/exits/etc, there's no sense throwing more data at
1618  * it.
1619  */
1620  flush_error = fflush(fout);
1621 
1622  /*
1623  * Check if we are at the end, if a cancel was pressed, or if there
1624  * were any errors either trying to flush out the results, or more
1625  * generally on the output stream at all. If we hit any errors
1626  * writing things to the stream, we presume $PAGER has disappeared and
1627  * stop bothering to pull down more data.
1628  */
1629  if (ntuples < fetch_count || cancel_pressed || flush_error ||
1630  ferror(fout))
1631  break;
1632  }
1633 
1634  if (pset.gfname)
1635  {
1636  /* close \g argument file/pipe */
1637  if (is_pipe)
1638  {
1639  pclose(fout);
1641  }
1642  else
1643  fclose(fout);
1644  }
1645  else if (is_pager)
1646  {
1647  /* close transient pager */
1648  ClosePager(fout);
1649  }
1650 
1651 cleanup:
1652  if (pset.timing)
1653  INSTR_TIME_SET_CURRENT(before);
1654 
1655  /*
1656  * We try to close the cursor on either success or failure, but on failure
1657  * ignore the result (it's probably just a bleat about being in an aborted
1658  * transaction)
1659  */
1660  results = PQexec(pset.db, "CLOSE _psql_cursor");
1661  if (OK)
1662  {
1663  OK = AcceptResult(results) &&
1664  (PQresultStatus(results) == PGRES_COMMAND_OK);
1665  ClearOrSaveResult(results);
1666  }
1667  else
1668  PQclear(results);
1669 
1670  if (started_txn)
1671  {
1672  results = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK");
1673  OK &= AcceptResult(results) &&
1674  (PQresultStatus(results) == PGRES_COMMAND_OK);
1675  ClearOrSaveResult(results);
1676  }
1677 
1678  if (pset.timing)
1679  {
1680  INSTR_TIME_SET_CURRENT(after);
1681  INSTR_TIME_SUBTRACT(after, before);
1682  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1683  }
1684 
1685  return OK;
1686 }
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:518
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:466
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:65
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:5966
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:852
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:815
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 2064 of file common.c.

References filename, fn(), free, get_home_path(), MAXPGPATH, NULL, psprintf(), and strlcpy().

Referenced by exec_command(), initializeInput(), parse_slash_copy(), and process_psqlrc().

2065 {
2066  if (!filename || !(*filename))
2067  return;
2068 
2069  /*
2070  * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2071  * for short versions of long file names, though the tilde is usually
2072  * toward the end, not at the beginning.
2073  */
2074 #ifndef WIN32
2075 
2076  /* try tilde expansion */
2077  if (**filename == '~')
2078  {
2079  char *fn;
2080  char oldp,
2081  *p;
2082  struct passwd *pw;
2083  char home[MAXPGPATH];
2084 
2085  fn = *filename;
2086  *home = '\0';
2087 
2088  p = fn + 1;
2089  while (*p != '/' && *p != '\0')
2090  p++;
2091 
2092  oldp = *p;
2093  *p = '\0';
2094 
2095  if (*(fn + 1) == '\0')
2096  get_home_path(home); /* ~ or ~/ only */
2097  else if ((pw = getpwnam(fn + 1)) != NULL)
2098  strlcpy(home, pw->pw_dir, sizeof(home)); /* ~user */
2099 
2100  *p = oldp;
2101  if (strlen(home) != 0)
2102  {
2103  char *newfn;
2104 
2105  newfn = psprintf("%s%s", home, p);
2106  free(fn);
2107  *filename = newfn;
2108  }
2109  }
2110 #endif
2111 
2112  return;
2113 }
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 261 of file common.c.

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

Referenced by setup_cancel_handler().

262 {
263  int save_errno = errno;
264  char errbuf[256];
265 
266  /* if we are waiting for input, longjmp out of it */
268  {
269  sigint_interrupt_enabled = false;
270  siglongjmp(sigint_interrupt_jmp, 1);
271  }
272 
273  /* else, set cancel flag to stop any long-running loops */
274  cancel_pressed = true;
275 
276  /* and send QueryCancel if we are processing a database query */
277  if (cancelConn != NULL)
278  {
279  if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
280  write_stderr("Cancel request sent\n");
281  else
282  {
283  write_stderr("Could not send cancel request: ");
284  write_stderr(errbuf);
285  }
286  }
287 
288  errno = save_errno; /* just in case the write changed it */
289 }
volatile bool sigint_interrupt_enabled
Definition: common.c:234
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:236
volatile bool cancel_pressed
Definition: print.c:46
#define write_stderr(str)
Definition: common.c:249
static PGcancel *volatile cancelConn
Definition: common.c:238
#define NULL
Definition: c.h:229
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
Definition: fe-connect.c:3844
static bool is_select_command ( const char *  query)
static

Definition at line 1956 of file common.c.

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

Referenced by SendQuery().

1957 {
1958  int wordlen;
1959 
1960  /*
1961  * First advance over any whitespace, comments and left parentheses.
1962  */
1963  for (;;)
1964  {
1965  query = skip_white_space(query);
1966  if (query[0] == '(')
1967  query++;
1968  else
1969  break;
1970  }
1971 
1972  /*
1973  * Check word length (since "selectx" is not "select").
1974  */
1975  wordlen = 0;
1976  while (isalpha((unsigned char) query[wordlen]))
1977  wordlen += PQmblen(&query[wordlen], pset.encoding);
1978 
1979  if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
1980  return true;
1981 
1982  if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
1983  return true;
1984 
1985  return false;
1986 }
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:1187
static const char * skip_white_space(const char *query)
Definition: common.c:1693
bool is_superuser ( void  )

Definition at line 1996 of file common.c.

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

Referenced by check_role(), check_session_authorization(), get_prompt(), pg_stat_statements_internal(), and SetSessionUserId().

1997 {
1998  const char *val;
1999 
2000  if (!pset.db)
2001  return false;
2002 
2003  val = PQparameterStatus(pset.db, "is_superuser");
2004 
2005  if (val && strcmp(val, "on") == 0)
2006  return true;
2007 
2008  return false;
2009 }
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:5976
long val
Definition: informix.c:689
void NoticeProcessor ( void *  arg,
const char *  message 
)

Definition at line 202 of file common.c.

References psql_error().

Referenced by do_connect(), and main().

203 {
204  (void) arg; /* not used */
205  psql_error("%s", message);
206 }
void psql_error(const char *fmt,...)
Definition: common.c:181
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:181
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
static void PrintNotifications ( void  )
static

Definition at line 748 of file common.c.

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

Referenced by SendQuery().

749 {
750  PGnotify *notify;
751 
752  while ((notify = PQnotifies(pset.db)))
753  {
754  /* for backward compatibility, only show payload if nonempty */
755  if (notify->extra[0])
756  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
757  notify->relname, notify->extra, notify->be_pid);
758  else
759  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
760  notify->relname, notify->be_pid);
761  fflush(pset.queryFout);
762  PQfreemem(notify);
763  }
764 }
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 1116 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().

1117 {
1118  bool success;
1119  const char *cmdstatus;
1120 
1121  if (!results)
1122  return false;
1123 
1124  switch (PQresultStatus(results))
1125  {
1126  case PGRES_TUPLES_OK:
1127  /* store or execute or print the data ... */
1128  if (pset.gset_prefix)
1129  success = StoreQueryTuple(results);
1130  else if (pset.gexec_flag)
1131  success = ExecQueryTuples(results);
1132  else if (pset.crosstab_flag)
1133  success = PrintResultsInCrosstab(results);
1134  else
1135  success = PrintQueryTuples(results);
1136  /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
1137  cmdstatus = PQcmdStatus(results);
1138  if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
1139  strncmp(cmdstatus, "UPDATE", 6) == 0 ||
1140  strncmp(cmdstatus, "DELETE", 6) == 0)
1141  PrintQueryStatus(results);
1142  break;
1143 
1144  case PGRES_COMMAND_OK:
1145  PrintQueryStatus(results);
1146  success = true;
1147  break;
1148 
1149  case PGRES_EMPTY_QUERY:
1150  success = true;
1151  break;
1152 
1153  case PGRES_COPY_OUT:
1154  case PGRES_COPY_IN:
1155  /* nothing to do here */
1156  success = true;
1157  break;
1158 
1159  case PGRES_BAD_RESPONSE:
1160  case PGRES_NONFATAL_ERROR:
1161  case PGRES_FATAL_ERROR:
1162  success = false;
1163  break;
1164 
1165  default:
1166  success = false;
1167  psql_error("unexpected PQresultStatus: %d\n",
1168  PQresultStatus(results));
1169  break;
1170  }
1171 
1172  fflush(pset.queryFout);
1173 
1174  return success;
1175 }
static void PrintQueryStatus(PGresult *results)
Definition: common.c:1084
char * gset_prefix
Definition: settings.h:95
PsqlSettings pset
Definition: startup.c:33
static bool ExecQueryTuples(const PGresult *result)
Definition: common.c:872
static bool PrintQueryTuples(const PGresult *results)
Definition: common.c:773
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:181
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:815
bool crosstab_flag
Definition: settings.h:97
static void PrintQueryStatus ( PGresult results)
static

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

1085 {
1086  char buf[16];
1087 
1088  if (!pset.quiet)
1089  {
1090  if (pset.popt.topt.format == PRINT_HTML)
1091  {
1092  fputs("<p>", pset.queryFout);
1094  fputs("</p>\n", pset.queryFout);
1095  }
1096  else
1097  fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
1098  }
1099 
1100  if (pset.logfile)
1101  fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
1102 
1103  snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
1104  SetVariable(pset.vars, "LASTOID", buf);
1105 }
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:65
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 773 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().

774 {
775  printQueryOpt my_popt = pset.popt;
776 
777  /* one-shot expanded output requested via \gx */
778  if (pset.g_expanded)
779  my_popt.topt.expanded = 1;
780 
781  /* write output to \g argument, if any */
782  if (pset.gfname)
783  {
784  FILE *fout;
785  bool is_pipe;
786 
787  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
788  return false;
789  if (is_pipe)
791 
792  printQuery(results, &my_popt, fout, false, pset.logfile);
793 
794  if (is_pipe)
795  {
796  pclose(fout);
798  }
799  else
800  fclose(fout);
801  }
802  else
803  printQuery(results, &my_popt, pset.queryFout, false, pset.logfile);
804 
805  return true;
806 }
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 544 of file common.c.

References _, and days.

Referenced by PSQLexecWatch(), and SendQuery().

545 {
546  double seconds;
547  double minutes;
548  double hours;
549  double days;
550 
551  if (elapsed_msec < 1000.0)
552  {
553  /* This is the traditional (pre-v10) output format */
554  printf(_("Time: %.3f ms\n"), elapsed_msec);
555  return;
556  }
557 
558  /*
559  * Note: we could print just seconds, in a format like %06.3f, when the
560  * total is less than 1min. But that's hard to interpret unless we tack
561  * on "s" or otherwise annotate it. Forcing the display to include
562  * minutes seems like a better solution.
563  */
564  seconds = elapsed_msec / 1000.0;
565  minutes = floor(seconds / 60.0);
566  seconds -= 60.0 * minutes;
567  if (minutes < 60.0)
568  {
569  printf(_("Time: %.3f ms (%02d:%06.3f)\n"),
570  elapsed_msec, (int) minutes, seconds);
571  return;
572  }
573 
574  hours = floor(minutes / 60.0);
575  minutes -= 60.0 * hours;
576  if (hours < 24.0)
577  {
578  printf(_("Time: %.3f ms (%02d:%02d:%06.3f)\n"),
579  elapsed_msec, (int) hours, (int) minutes, seconds);
580  return;
581  }
582 
583  days = floor(hours / 24.0);
584  hours -= 24.0 * days;
585  printf(_("Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n"),
586  elapsed_msec, days, (int) hours, (int) minutes, seconds);
587 }
const char *const days[]
Definition: datetime.c:69
#define _(x)
Definition: elog.c:84
static bool ProcessResult ( PGresult **  results)
static

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

957 {
958  bool success = true;
959  bool first_cycle = true;
960 
961  for (;;)
962  {
963  ExecStatusType result_status;
964  bool is_copy;
965  PGresult *next_result;
966 
967  if (!AcceptResult(*results))
968  {
969  /*
970  * Failure at this point is always a server-side failure or a
971  * failure to submit the command string. Either way, we're
972  * finished with this command string.
973  */
974  success = false;
975  break;
976  }
977 
978  result_status = PQresultStatus(*results);
979  switch (result_status)
980  {
981  case PGRES_EMPTY_QUERY:
982  case PGRES_COMMAND_OK:
983  case PGRES_TUPLES_OK:
984  is_copy = false;
985  break;
986 
987  case PGRES_COPY_OUT:
988  case PGRES_COPY_IN:
989  is_copy = true;
990  break;
991 
992  default:
993  /* AcceptResult() should have caught anything else. */
994  is_copy = false;
995  psql_error("unexpected PQresultStatus: %d\n", result_status);
996  break;
997  }
998 
999  if (is_copy)
1000  {
1001  /*
1002  * Marshal the COPY data. Either subroutine will get the
1003  * connection out of its COPY state, then call PQresultStatus()
1004  * once and report any error.
1005  *
1006  * If pset.copyStream is set, use that as data source/sink,
1007  * otherwise use queryFout or cur_cmd_source as appropriate.
1008  */
1009  FILE *copystream = pset.copyStream;
1010  PGresult *copy_result;
1011 
1012  SetCancelConn();
1013  if (result_status == PGRES_COPY_OUT)
1014  {
1015  if (!copystream)
1016  copystream = pset.queryFout;
1017  success = handleCopyOut(pset.db,
1018  copystream,
1019  &copy_result) && success;
1020 
1021  /*
1022  * Suppress status printing if the report would go to the same
1023  * place as the COPY data just went. Note this doesn't
1024  * prevent error reporting, since handleCopyOut did that.
1025  */
1026  if (copystream == pset.queryFout)
1027  {
1028  PQclear(copy_result);
1029  copy_result = NULL;
1030  }
1031  }
1032  else
1033  {
1034  if (!copystream)
1035  copystream = pset.cur_cmd_source;
1036  success = handleCopyIn(pset.db,
1037  copystream,
1038  PQbinaryTuples(*results),
1039  &copy_result) && success;
1040  }
1041  ResetCancelConn();
1042 
1043  /*
1044  * Replace the PGRES_COPY_OUT/IN result with COPY command's exit
1045  * status, or with NULL if we want to suppress printing anything.
1046  */
1047  PQclear(*results);
1048  *results = copy_result;
1049  }
1050  else if (first_cycle)
1051  {
1052  /* fast path: no COPY commands; PQexec visited all results */
1053  break;
1054  }
1055 
1056  /*
1057  * Check PQgetResult() again. In the typical case of a single-command
1058  * string, it will return NULL. Otherwise, we'll have other results
1059  * to process that may include other COPYs. We keep the last result.
1060  */
1061  next_result = PQgetResult(pset.db);
1062  if (!next_result)
1063  break;
1064 
1065  PQclear(*results);
1066  *results = next_result;
1067  first_cycle = false;
1068  }
1069 
1070  /* may need this to recover from conn loss during COPY */
1071  if (!first_cycle && !CheckConnection())
1072  return false;
1073 
1074  return success;
1075 }
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:367
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:466
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:406
void psql_error(const char *fmt,...)
Definition: common.c:181
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:436
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
void psql_error ( const char *  fmt,
  ... 
)

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

182 {
183  va_list ap;
184 
185  fflush(stdout);
186  if (pset.queryFout && pset.queryFout != stdout)
187  fflush(pset.queryFout);
188 
189  if (pset.inputfile)
190  fprintf(stderr, "%s:%s:" UINT64_FORMAT ": ", pset.progname, pset.inputfile, pset.lineno);
191  va_start(ap, fmt);
192  vfprintf(stderr, _(fmt), ap);
193  va_end(ap);
194 }
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,
bool  escape,
bool  as_ident,
void *  passthrough 
)

Definition at line 127 of file common.c.

References _psqlSettings::db, error(), GetVariable(), NULL, pg_strdup(), PQerrorMessage(), PQescapeIdentifier(), PQescapeLiteral(), PQfreemem(), pset, psql_error(), result, value, and _psqlSettings::vars.

129 {
130  char *result;
131  const char *value;
132 
133  value = GetVariable(pset.vars, varname);
134  if (!value)
135  return NULL;
136 
137  if (escape)
138  {
139  char *escaped_value;
140 
141  if (!pset.db)
142  {
143  psql_error("cannot escape without active connection\n");
144  return NULL;
145  }
146 
147  if (as_ident)
148  escaped_value =
149  PQescapeIdentifier(pset.db, value, strlen(value));
150  else
151  escaped_value =
152  PQescapeLiteral(pset.db, value, strlen(value));
153 
154  if (escaped_value == NULL)
155  {
156  const char *error = PQerrorMessage(pset.db);
157 
158  psql_error("%s", error);
159  return NULL;
160  }
161 
162  /*
163  * Rather than complicate the lexer's API with a notion of which
164  * free() routine to use, just pay the price of an extra strdup().
165  */
166  result = pg_strdup(escaped_value);
167  PQfreemem(escaped_value);
168  }
169  else
170  result = pg_strdup(value);
171 
172  return result;
173 }
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6011
PsqlSettings pset
Definition: startup.c:33
static void error(void)
Definition: sql-dyntest.c:147
return result
Definition: formatting.c:1618
static struct @114 value
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3474
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:181
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3468
#define NULL
Definition: c.h:229
void PQfreemem(void *ptr)
Definition: fe-exec.c:3200
VariableSpace vars
Definition: settings.h:116
PGresult* PSQLexec ( const char *  query)

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

604 {
605  PGresult *res;
606 
607  if (!pset.db)
608  {
609  psql_error("You are currently not connected to a database.\n");
610  return NULL;
611  }
612 
614  {
615  printf(_("********* QUERY **********\n"
616  "%s\n"
617  "**************************\n\n"), query);
618  fflush(stdout);
619  if (pset.logfile)
620  {
621  fprintf(pset.logfile,
622  _("********* QUERY **********\n"
623  "%s\n"
624  "**************************\n\n"), query);
625  fflush(pset.logfile);
626  }
627 
629  return NULL;
630  }
631 
632  SetCancelConn();
633 
634  res = PQexec(pset.db, query);
635 
636  ResetCancelConn();
637 
638  if (!AcceptResult(res))
639  {
640  ClearOrSaveResult(res);
641  res = NULL;
642  }
643 
644  return res;
645 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:518
static bool AcceptResult(const PGresult *result)
Definition: common.c:466
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:132
void SetCancelConn(void)
Definition: common.c:406
void psql_error(const char *fmt,...)
Definition: common.c:181
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:436
#define _(x)
Definition: elog.c:84
int PSQLexecWatch ( const char *  query,
const printQueryOpt opt 
)

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

659 {
660  PGresult *res;
661  double elapsed_msec = 0;
663  instr_time after;
664 
665  if (!pset.db)
666  {
667  psql_error("You are currently not connected to a database.\n");
668  return 0;
669  }
670 
671  SetCancelConn();
672 
673  if (pset.timing)
674  INSTR_TIME_SET_CURRENT(before);
675 
676  res = PQexec(pset.db, query);
677 
678  ResetCancelConn();
679 
680  if (!AcceptResult(res))
681  {
682  ClearOrSaveResult(res);
683  return 0;
684  }
685 
686  if (pset.timing)
687  {
688  INSTR_TIME_SET_CURRENT(after);
689  INSTR_TIME_SUBTRACT(after, before);
690  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
691  }
692 
693  /*
694  * If SIGINT is sent while the query is processing, the interrupt will be
695  * consumed. The user's intention, though, is to cancel the entire watch
696  * process, so detect a sent cancellation request and exit in this case.
697  */
698  if (cancel_pressed)
699  {
700  PQclear(res);
701  return 0;
702  }
703 
704  switch (PQresultStatus(res))
705  {
706  case PGRES_TUPLES_OK:
707  printQuery(res, opt, pset.queryFout, false, pset.logfile);
708  break;
709 
710  case PGRES_COMMAND_OK:
711  fprintf(pset.queryFout, "%s\n%s\n\n", opt->title, PQcmdStatus(res));
712  break;
713 
714  case PGRES_EMPTY_QUERY:
715  psql_error(_("\\watch cannot be used with an empty query\n"));
716  PQclear(res);
717  return -1;
718 
719  case PGRES_COPY_OUT:
720  case PGRES_COPY_IN:
721  case PGRES_COPY_BOTH:
722  psql_error(_("\\watch cannot be used with COPY\n"));
723  PQclear(res);
724  return -1;
725 
726  default:
727  psql_error(_("unexpected result status for \\watch\n"));
728  PQclear(res);
729  return -1;
730  }
731 
732  PQclear(res);
733 
734  fflush(pset.queryFout);
735 
736  /* Possible microtiming output */
737  if (pset.timing)
738  PrintTiming(elapsed_msec);
739 
740  return 1;
741 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:518
#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:544
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:466
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:406
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2944
void psql_error(const char *fmt,...)
Definition: common.c:181
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:436
#define _(x)
Definition: elog.c:84
static bool recognized_connection_string ( const char *  connstr)

Definition at line 2151 of file common.c.

References NULL, and uri_prefix_length().

Referenced by do_connect().

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

Definition at line 436 of file common.c.

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

437 {
438  PGcancel *oldCancelConn;
439 
440 #ifdef WIN32
441  EnterCriticalSection(&cancelConnLock);
442 #endif
443 
444  oldCancelConn = cancelConn;
445  /* be sure handle_sigint doesn't use pointer while freeing */
446  cancelConn = NULL;
447 
448  if (oldCancelConn != NULL)
449  PQfreeCancel(oldCancelConn);
450 
451 #ifdef WIN32
452  LeaveCriticalSection(&cancelConnLock);
453 #endif
454 }
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:3712
static PGcancel *volatile cancelConn
Definition: common.c:238
#define NULL
Definition: c.h:229
bool SendQuery ( const char *  query)

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

1192 {
1193  PGresult *results;
1194  PGTransactionStatusType transaction_status;
1195  double elapsed_msec = 0;
1196  bool OK = false;
1197  int i;
1198  bool on_error_rollback_savepoint = false;
1199  static bool on_error_rollback_warning = false;
1200 
1201  if (!pset.db)
1202  {
1203  psql_error("You are currently not connected to a database.\n");
1204  goto sendquery_cleanup;
1205  }
1206 
1207  if (pset.singlestep)
1208  {
1209  char buf[3];
1210 
1211  fflush(stderr);
1212  printf(_("***(Single step mode: verify command)*******************************************\n"
1213  "%s\n"
1214  "***(press return to proceed or enter x and return to cancel)********************\n"),
1215  query);
1216  fflush(stdout);
1217  if (fgets(buf, sizeof(buf), stdin) != NULL)
1218  if (buf[0] == 'x')
1219  goto sendquery_cleanup;
1220  if (cancel_pressed)
1221  goto sendquery_cleanup;
1222  }
1223  else if (pset.echo == PSQL_ECHO_QUERIES)
1224  {
1225  puts(query);
1226  fflush(stdout);
1227  }
1228 
1229  if (pset.logfile)
1230  {
1231  fprintf(pset.logfile,
1232  _("********* QUERY **********\n"
1233  "%s\n"
1234  "**************************\n\n"), query);
1235  fflush(pset.logfile);
1236  }
1237 
1238  SetCancelConn();
1239 
1240  transaction_status = PQtransactionStatus(pset.db);
1241 
1242  if (transaction_status == PQTRANS_IDLE &&
1243  !pset.autocommit &&
1244  !command_no_begin(query))
1245  {
1246  results = PQexec(pset.db, "BEGIN");
1247  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1248  {
1249  psql_error("%s", PQerrorMessage(pset.db));
1250  ClearOrSaveResult(results);
1251  ResetCancelConn();
1252  goto sendquery_cleanup;
1253  }
1254  ClearOrSaveResult(results);
1255  transaction_status = PQtransactionStatus(pset.db);
1256  }
1257 
1258  if (transaction_status == PQTRANS_INTRANS &&
1262  {
1263  if (on_error_rollback_warning == false && pset.sversion < 80000)
1264  {
1265  char sverbuf[32];
1266 
1267  psql_error("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n",
1269  sverbuf, sizeof(sverbuf)));
1270  on_error_rollback_warning = true;
1271  }
1272  else
1273  {
1274  results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
1275  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1276  {
1277  psql_error("%s", PQerrorMessage(pset.db));
1278  ClearOrSaveResult(results);
1279  ResetCancelConn();
1280  goto sendquery_cleanup;
1281  }
1282  ClearOrSaveResult(results);
1283  on_error_rollback_savepoint = true;
1284  }
1285  }
1286 
1287  if (pset.fetch_count <= 0 || pset.gexec_flag ||
1289  {
1290  /* Default fetch-it-all-and-print mode */
1292  after;
1293 
1294  if (pset.timing)
1295  INSTR_TIME_SET_CURRENT(before);
1296 
1297  results = PQexec(pset.db, query);
1298 
1299  /* these operations are included in the timing result: */
1300  ResetCancelConn();
1301  OK = ProcessResult(&results);
1302 
1303  if (pset.timing)
1304  {
1305  INSTR_TIME_SET_CURRENT(after);
1306  INSTR_TIME_SUBTRACT(after, before);
1307  elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1308  }
1309 
1310  /* but printing results isn't: */
1311  if (OK && results)
1312  OK = PrintQueryResults(results);
1313  }
1314  else
1315  {
1316  /* Fetch-in-segments mode */
1317  OK = ExecQueryUsingCursor(query, &elapsed_msec);
1318  ResetCancelConn();
1319  results = NULL; /* PQclear(NULL) does nothing */
1320  }
1321 
1322  if (!OK && pset.echo == PSQL_ECHO_ERRORS)
1323  psql_error("STATEMENT: %s\n", query);
1324 
1325  /* If we made a temporary savepoint, possibly release/rollback */
1326  if (on_error_rollback_savepoint)
1327  {
1328  const char *svptcmd = NULL;
1329 
1330  transaction_status = PQtransactionStatus(pset.db);
1331 
1332  switch (transaction_status)
1333  {
1334  case PQTRANS_INERROR:
1335  /* We always rollback on an error */
1336  svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
1337  break;
1338 
1339  case PQTRANS_IDLE:
1340  /* If they are no longer in a transaction, then do nothing */
1341  break;
1342 
1343  case PQTRANS_INTRANS:
1344 
1345  /*
1346  * Do nothing if they are messing with savepoints themselves:
1347  * If the user did RELEASE or ROLLBACK, our savepoint is gone.
1348  * If they issued a SAVEPOINT, releasing ours would remove
1349  * theirs.
1350  */
1351  if (results &&
1352  (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
1353  strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
1354  strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
1355  svptcmd = NULL;
1356  else
1357  svptcmd = "RELEASE pg_psql_temporary_savepoint";
1358  break;
1359 
1360  case PQTRANS_ACTIVE:
1361  case PQTRANS_UNKNOWN:
1362  default:
1363  OK = false;
1364  /* PQTRANS_UNKNOWN is expected given a broken connection. */
1365  if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp())
1366  psql_error("unexpected transaction status (%d)\n",
1367  transaction_status);
1368  break;
1369  }
1370 
1371  if (svptcmd)
1372  {
1373  PGresult *svptres;
1374 
1375  svptres = PQexec(pset.db, svptcmd);
1376  if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
1377  {
1378  psql_error("%s", PQerrorMessage(pset.db));
1379  ClearOrSaveResult(svptres);
1380  OK = false;
1381 
1382  PQclear(results);
1383  ResetCancelConn();
1384  goto sendquery_cleanup;
1385  }
1386  PQclear(svptres);
1387  }
1388  }
1389 
1390  ClearOrSaveResult(results);
1391 
1392  /* Possible microtiming output */
1393  if (pset.timing)
1394  PrintTiming(elapsed_msec);
1395 
1396  /* check for events that may occur during query execution */
1397 
1398  if (pset.encoding != PQclientEncoding(pset.db) &&
1399  PQclientEncoding(pset.db) >= 0)
1400  {
1401  /* track effects of SET CLIENT_ENCODING */
1404  SetVariable(pset.vars, "ENCODING",
1406  }
1407 
1409 
1410  /* perform cleanup that should occur after any attempted query */
1411 
1412 sendquery_cleanup:
1413 
1414  /* reset \g's output-to-filename trigger */
1415  if (pset.gfname)
1416  {
1417  free(pset.gfname);
1418  pset.gfname = NULL;
1419  }
1420 
1421  /* reset \gx's expanded-mode flag */
1422  pset.g_expanded = false;
1423 
1424  /* reset \gset trigger */
1425  if (pset.gset_prefix)
1426  {
1428  pset.gset_prefix = NULL;
1429  }
1430 
1431  /* reset \gexec trigger */
1432  pset.gexec_flag = false;
1433 
1434  /* reset \crosstabview trigger */
1435  pset.crosstab_flag = false;
1436  for (i = 0; i < lengthof(pset.ctv_args); i++)
1437  {
1438  pg_free(pset.ctv_args[i]);
1439  pset.ctv_args[i] = NULL;
1440  }
1441 
1442  return OK;
1443 }
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:1116
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6011
int encoding
Definition: print.h:118
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:518
#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:544
static bool ConnectionUp(void)
Definition: common.c:349
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:6071
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:748
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:1956
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:167
static char * buf
Definition: pg_test_fsync.c:65
int fetch_count
Definition: settings.h:128
static bool ProcessResult(PGresult **results)
Definition: common.c:956
bool g_expanded
Definition: settings.h:94
void SetCancelConn(void)
Definition: common.c:406
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1457
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:5966
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2944
void psql_error(const char *fmt,...)
Definition: common.c:181
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:1757
void ResetCancelConn(void)
Definition: common.c:436
#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 2043 of file common.c.

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

Referenced by get_prompt().

2044 {
2045  const char *val;
2046 
2047  if (!pset.db)
2048  return NULL;
2049 
2050  val = PQparameterStatus(pset.db, "session_authorization");
2051  if (val)
2052  return val;
2053  else
2054  return PQuser(pset.db);
2055 }
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:5976
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:5887
#define NULL
Definition: c.h:229
long val
Definition: informix.c:689
void SetCancelConn ( void  )

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

407 {
408  PGcancel *oldCancelConn;
409 
410 #ifdef WIN32
411  EnterCriticalSection(&cancelConnLock);
412 #endif
413 
414  /* Free the old one if we have one */
415  oldCancelConn = cancelConn;
416  /* be sure handle_sigint doesn't use pointer while freeing */
417  cancelConn = NULL;
418 
419  if (oldCancelConn != NULL)
420  PQfreeCancel(oldCancelConn);
421 
423 
424 #ifdef WIN32
425  LeaveCriticalSection(&cancelConnLock);
426 #endif
427 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:33
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:3712
PGcancel * PQgetCancel(PGconn *conn)
Definition: fe-connect.c:3689
static PGcancel *volatile cancelConn
Definition: common.c:238
#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(), 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 292 of file common.c.

293 {
294  pqsignal(SIGINT, handle_sigint);
295 }
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
static void handle_sigint(SIGNAL_ARGS)
Definition: common.c:261
static const char* skip_white_space ( const char *  query)
static

Definition at line 1693 of file common.c.

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

Referenced by command_no_begin(), and is_select_command().

1694 {
1695  int cnestlevel = 0; /* slash-star comment nest level */
1696 
1697  while (*query)
1698  {
1699  int mblen = PQmblen(query, pset.encoding);
1700 
1701  /*
1702  * Note: we assume the encoding is a superset of ASCII, so that for
1703  * example "query[0] == '/'" is meaningful. However, we do NOT assume
1704  * that the second and subsequent bytes of a multibyte character
1705  * couldn't look like ASCII characters; so it is critical to advance
1706  * by mblen, not 1, whenever we haven't exactly identified the
1707  * character we are skipping over.
1708  */
1709  if (isspace((unsigned char) *query))
1710  query += mblen;
1711  else if (query[0] == '/' && query[1] == '*')
1712  {
1713  cnestlevel++;
1714  query += 2;
1715  }
1716  else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
1717  {
1718  cnestlevel--;
1719  query += 2;
1720  }
1721  else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
1722  {
1723  query += 2;
1724 
1725  /*
1726  * We have to skip to end of line since any slash-star inside the
1727  * -- comment does NOT start a slash-star comment.
1728  */
1729  while (*query)
1730  {
1731  if (*query == '\n')
1732  {
1733  query++;
1734  break;
1735  }
1736  query += PQmblen(query, pset.encoding);
1737  }
1738  }
1739  else if (cnestlevel > 0)
1740  query += mblen;
1741  else
1742  break; /* found first token */
1743  }
1744 
1745  return query;
1746 }
PsqlSettings pset
Definition: startup.c:33
int encoding
Definition: settings.h:83
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1187
bool standard_strings ( void  )

Definition at line 2019 of file common.c.

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

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

2020 {
2021  const char *val;
2022 
2023  if (!pset.db)
2024  return false;
2025 
2026  val = PQparameterStatus(pset.db, "standard_conforming_strings");
2027 
2028  if (val && strcmp(val, "on") == 0)
2029  return true;
2030 
2031  return false;
2032 }
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:5976
long val
Definition: informix.c:689
static bool StoreQueryTuple ( const PGresult result)
static

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

816 {
817  bool success = true;
818 
819  if (PQntuples(result) < 1)
820  {
821  psql_error("no rows returned for \\gset\n");
822  success = false;
823  }
824  else if (PQntuples(result) > 1)
825  {
826  psql_error("more than one row returned for \\gset\n");
827  success = false;
828  }
829  else
830  {
831  int i;
832 
833  for (i = 0; i < PQnfields(result); i++)
834  {
835  char *colname = PQfname(result, i);
836  char *varname;
837  char *value;
838 
839  /* concatenate prefix and column name */
840  varname = psprintf("%s%s", pset.gset_prefix, colname);
841 
842  if (!PQgetisnull(result, 0, i))
843  value = PQgetvalue(result, 0, i);
844  else
845  {
846  /* for NULL value, unset rather than set the variable */
847  value = NULL;
848  }
849 
850  if (!SetVariable(pset.vars, varname, value))
851  {
852  free(varname);
853  success = false;
854  break;
855  }
856 
857  free(varname);
858  }
859  }
860 
861  return success;
862 }
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 struct @114 value
static bool success
Definition: pg_basebackup.c:96
void psql_error(const char *fmt,...)
Definition: common.c:181
#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
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 2124 of file common.c.

References short_uri_designator, and uri_designator.

Referenced by recognized_connection_string().

2125 {
2126  /* The connection URI must start with either of the following designators: */
2127  static const char uri_designator[] = "postgresql://";
2128  static const char short_uri_designator[] = "postgres://";
2129 
2130  if (strncmp(connstr, uri_designator,
2131  sizeof(uri_designator) - 1) == 0)
2132  return sizeof(uri_designator) - 1;
2133 
2134  if (strncmp(connstr, short_uri_designator,
2135  sizeof(short_uri_designator) - 1) == 0)
2136  return sizeof(short_uri_designator) - 1;
2137 
2138  return 0;
2139 }
static const char short_uri_designator[]
Definition: fe-connect.c:336
static const char uri_designator[]
Definition: fe-connect.c:335
static char * connstr
Definition: pg_dumpall.c:64

Variable Documentation

PGcancel* volatile cancelConn = NULL
static

Definition at line 238 of file common.c.

Referenced by ResetCancelConn(), and SetCancelConn().

volatile bool sigint_interrupt_enabled = false
sigjmp_buf sigint_interrupt_jmp

Definition at line 236 of file common.c.

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