PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
common.c
Go to the documentation of this file.
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2017, PostgreSQL Global Development Group
5  *
6  * src/bin/psql/common.c
7  */
8 #include "postgres_fe.h"
9 #include "common.h"
10 
11 #include <ctype.h>
12 #include <limits.h>
13 #include <math.h>
14 #include <signal.h>
15 #ifndef WIN32
16 #include <unistd.h> /* for write() */
17 #else
18 #include <io.h> /* for _write() */
19 #include <win32.h>
20 #endif
21 
22 #include "fe_utils/string_utils.h"
23 #include "portability/instr_time.h"
24 
25 #include "settings.h"
26 #include "command.h"
27 #include "copy.h"
28 #include "crosstabview.h"
29 #include "fe_utils/mbprint.h"
30 
31 
32 static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec);
33 static bool command_no_begin(const char *query);
34 static bool is_select_command(const char *query);
35 
36 
37 /*
38  * openQueryOutputFile --- attempt to open a query output file
39  *
40  * fname == NULL selects stdout, else an initial '|' selects a pipe,
41  * else plain file.
42  *
43  * Returns output file pointer into *fout, and is-a-pipe flag into *is_pipe.
44  * Caller is responsible for adjusting SIGPIPE state if it's a pipe.
45  *
46  * On error, reports suitable error message and returns FALSE.
47  */
48 bool
49 openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
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 }
75 
76 /*
77  * setQFout
78  * -- handler for -o command line option and \o command
79  *
80  * On success, updates pset with the new output file and returns true.
81  * On failure, returns false without changing pset state.
82  */
83 bool
84 setQFout(const char *fname)
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 }
111 
112 
113 /*
114  * Variable-fetching callback for flex lexer
115  *
116  * If the specified variable exists, return its value as a string (malloc'd
117  * and expected to be freed by the caller); else return NULL.
118  *
119  * If "quote" isn't PQUOTE_PLAIN, then return the value suitably quoted and
120  * escaped for the specified quoting requirement. (Failure in escaping
121  * should lead to printing an error and returning NULL.)
122  *
123  * "passthrough" is the pointer previously given to psql_scan_set_passthrough.
124  * In psql, passthrough points to a ConditionalStack, which we check to
125  * determine whether variable expansion is allowed.
126  */
127 char *
128 psql_get_variable(const char *varname, PsqlScanQuoteType quote,
129  void *passthrough)
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 }
213 
214 
215 /*
216  * Error reporting for scripts. Errors should look like
217  * psql:filename:lineno: message
218  */
219 void
220 psql_error(const char *fmt,...)
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 }
234 
235 
236 
237 /*
238  * for backend Notice messages (INFO, WARNING, etc)
239  */
240 void
241 NoticeProcessor(void *arg, const char *message)
242 {
243  (void) arg; /* not used */
244  psql_error("%s", message);
245 }
246 
247 
248 
249 /*
250  * Code to support query cancellation
251  *
252  * Before we start a query, we enable the SIGINT signal catcher to send a
253  * cancel request to the backend. Note that sending the cancel directly from
254  * the signal handler is safe because PQcancel() is written to make it
255  * so. We use write() to report to stderr because it's better to use simple
256  * facilities in a signal handler.
257  *
258  * On win32, the signal canceling happens on a separate thread, because
259  * that's how SetConsoleCtrlHandler works. The PQcancel function is safe
260  * for this (unlike PQrequestCancel). However, a CRITICAL_SECTION is required
261  * to protect the PGcancel structure against being changed while the signal
262  * thread is using it.
263  *
264  * SIGINT is supposed to abort all long-running psql operations, not only
265  * database queries. In most places, this is accomplished by checking
266  * cancel_pressed during long-running loops. However, that won't work when
267  * blocked on user input (in readline() or fgets()). In those places, we
268  * set sigint_interrupt_enabled TRUE while blocked, instructing the signal
269  * catcher to longjmp through sigint_interrupt_jmp. We assume readline and
270  * fgets are coded to handle possible interruption. (XXX currently this does
271  * not work on win32, so control-C is less useful there)
272  */
273 volatile bool sigint_interrupt_enabled = false;
274 
276 
277 static PGcancel *volatile cancelConn = NULL;
278 
279 #ifdef WIN32
280 static CRITICAL_SECTION cancelConnLock;
281 #endif
282 
283 /*
284  * Write a simple string to stderr --- must be safe in a signal handler.
285  * We ignore the write() result since there's not much we could do about it.
286  * Certain compilers make that harder than it ought to be.
287  */
288 #define write_stderr(str) \
289  do { \
290  const char *str_ = (str); \
291  int rc_; \
292  rc_ = write(fileno(stderr), str_, strlen(str_)); \
293  (void) rc_; \
294  } while (0)
295 
296 
297 #ifndef WIN32
298 
299 static void
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 }
329 
330 void
332 {
333  pqsignal(SIGINT, handle_sigint);
334 }
335 #else /* WIN32 */
336 
337 static BOOL WINAPI
338 consoleHandler(DWORD dwCtrlType)
339 {
340  char errbuf[256];
341 
342  if (dwCtrlType == CTRL_C_EVENT ||
343  dwCtrlType == CTRL_BREAK_EVENT)
344  {
345  /*
346  * Can't longjmp here, because we are in wrong thread :-(
347  */
348 
349  /* set cancel flag to stop any long-running loops */
350  cancel_pressed = true;
351 
352  /* and send QueryCancel if we are processing a database query */
353  EnterCriticalSection(&cancelConnLock);
354  if (cancelConn != NULL)
355  {
356  if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
357  write_stderr("Cancel request sent\n");
358  else
359  {
360  write_stderr("Could not send cancel request: ");
361  write_stderr(errbuf);
362  }
363  }
364  LeaveCriticalSection(&cancelConnLock);
365 
366  return TRUE;
367  }
368  else
369  /* Return FALSE for any signals not being handled */
370  return FALSE;
371 }
372 
373 void
375 {
376  InitializeCriticalSection(&cancelConnLock);
377 
378  SetConsoleCtrlHandler(consoleHandler, TRUE);
379 }
380 #endif /* WIN32 */
381 
382 
383 /* ConnectionUp
384  *
385  * Returns whether our backend connection is still there.
386  */
387 static bool
389 {
390  return PQstatus(pset.db) != CONNECTION_BAD;
391 }
392 
393 
394 
395 /* CheckConnection
396  *
397  * Verify that we still have a good connection to the backend, and if not,
398  * see if it can be restored.
399  *
400  * Returns true if either the connection was still there, or it could be
401  * restored successfully; false otherwise. If, however, there was no
402  * connection and the session is non-interactive, this will exit the program
403  * with a code of EXIT_BADCONN.
404  */
405 static bool
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 }
436 
437 
438 
439 /*
440  * SetCancelConn
441  *
442  * Set cancelConn to point to the current database connection.
443  */
444 void
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 
461  cancelConn = PQgetCancel(pset.db);
462 
463 #ifdef WIN32
464  LeaveCriticalSection(&cancelConnLock);
465 #endif
466 }
467 
468 
469 /*
470  * ResetCancelConn
471  *
472  * Free the current cancel connection, if any, and set to NULL.
473  */
474 void
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 }
494 
495 
496 /*
497  * AcceptResult
498  *
499  * Checks whether a result is valid, giving an error message if necessary;
500  * and ensures that the connection to the backend is still up.
501  *
502  * Returns true for valid result, false for error state.
503  */
504 static bool
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 }
548 
549 
550 /*
551  * ClearOrSaveResult
552  *
553  * If the result represents an error, remember it for possible display by
554  * \errverbose. Otherwise, just PQclear() it.
555  */
556 static void
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 }
576 
577 
578 /*
579  * Print microtiming output. Always print raw milliseconds; if the interval
580  * is >= 1 second, also break it down into days/hours/minutes/seconds.
581  */
582 static void
583 PrintTiming(double elapsed_msec)
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 }
627 
628 
629 /*
630  * PSQLexec
631  *
632  * This is the way to send "backdoor" queries (those not directly entered
633  * by the user). It is subject to -E but not -e.
634  *
635  * Caller is responsible for handling the ensuing processing if a COPY
636  * command is sent.
637  *
638  * Note: we don't bother to check PQclientEncoding; it is assumed that no
639  * caller uses this path to issue "SET CLIENT_ENCODING".
640  */
641 PGresult *
642 PSQLexec(const char *query)
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 }
685 
686 
687 /*
688  * PSQLexecWatch
689  *
690  * This function is used for \watch command to send the query to
691  * the server and print out the results.
692  *
693  * Returns 1 if the query executed successfully, 0 if it cannot be repeated,
694  * e.g., because of the interrupt, -1 on error.
695  */
696 int
697 PSQLexecWatch(const char *query, const printQueryOpt *opt)
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 }
781 
782 
783 /*
784  * PrintNotifications: check for asynchronous notifications, and print them out
785  */
786 static void
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 }
804 
805 
806 /*
807  * PrintQueryTuples: assuming query result is OK, print its tuples
808  *
809  * Returns true if successful, false otherwise.
810  */
811 static bool
812 PrintQueryTuples(const PGresult *results)
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 }
846 
847 
848 /*
849  * StoreQueryTuple: assuming query result is OK, save data into variables
850  *
851  * Returns true if successful, false otherwise.
852  */
853 static bool
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 }
902 
903 
904 /*
905  * ExecQueryTuples: assuming query result is OK, execute each query
906  * result field as a SQL statement
907  *
908  * Returns true if successful, false otherwise.
909  */
910 static bool
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 }
972 
973 
974 /*
975  * ProcessResult: utility function for use by SendQuery() only
976  *
977  * When our command string contained a COPY FROM STDIN or COPY TO STDOUT,
978  * PQexec() has stopped at the PGresult associated with the first such
979  * command. In that event, we'll marshal data for the COPY and then cycle
980  * through any subsequent PGresult objects.
981  *
982  * When the command string contained no such COPY command, this function
983  * degenerates to an AcceptResult() call.
984  *
985  * Changes its argument to point to the last PGresult of the command string,
986  * or NULL if that result was for a COPY TO STDOUT. (Returning NULL prevents
987  * the command status from being printed, which we want in that case so that
988  * the status line doesn't get taken as part of the COPY data.)
989  *
990  * Returns true on complete success, false otherwise. Possible failure modes
991  * include purely client-side problems; check the transaction status for the
992  * server-side opinion.
993  */
994 static bool
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 }
1115 
1116 
1117 /*
1118  * PrintQueryStatus: report command status as required
1119  *
1120  * Note: Utility function for use by PrintQueryResults() only.
1121  */
1122 static void
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 }
1145 
1146 
1147 /*
1148  * PrintQueryResults: print out (or store or execute) query results as required
1149  *
1150  * Note: Utility function for use by SendQuery() only.
1151  *
1152  * Returns true if the query executed successfully, false otherwise.
1153  */
1154 static bool
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 }
1215 
1216 
1217 /*
1218  * SendQuery: send the query string to the backend
1219  * (and print out results)
1220  *
1221  * Note: This is the "front door" way to send a query. That is, use it to
1222  * send queries actually entered by the user. These queries will be subject to
1223  * single step mode.
1224  * To send "back door" queries (generated by slash commands, etc.) in a
1225  * controlled way, use PSQLexec().
1226  *
1227  * Returns true if the query executed successfully, false otherwise.
1228  */
1229 bool
1230 SendQuery(const char *query)
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 }
1483 
1484 
1485 /*
1486  * ExecQueryUsingCursor: run a SELECT-like query using a cursor
1487  *
1488  * This feature allows result sets larger than RAM to be dealt with.
1489  *
1490  * Returns true if the query executed successfully, false otherwise.
1491  *
1492  * If pset.timing is on, total query time (exclusive of result-printing) is
1493  * stored into *elapsed_msec.
1494  */
1495 static bool
1496 ExecQueryUsingCursor(const char *query, double *elapsed_msec)
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 }
1726 
1727 
1728 /*
1729  * Advance the given char pointer over white space and SQL comments.
1730  */
1731 static const char *
1732 skip_white_space(const char *query)
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 }
1786 
1787 
1788 /*
1789  * Check whether a command is one of those for which we should NOT start
1790  * a new transaction block (ie, send a preceding BEGIN).
1791  *
1792  * These include the transaction control statements themselves, plus
1793  * certain statements that the backend disallows inside transaction blocks.
1794  */
1795 static bool
1796 command_no_begin(const char *query)
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 }
1989 
1990 
1991 /*
1992  * Check whether the specified command is a SELECT (or VALUES).
1993  */
1994 static bool
1995 is_select_command(const char *query)
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 }
2026 
2027 
2028 /*
2029  * Test if the current user is a database superuser.
2030  *
2031  * Note: this will correctly detect superuserness only with a protocol-3.0
2032  * or newer backend; otherwise it will always say "false".
2033  */
2034 bool
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 }
2049 
2050 
2051 /*
2052  * Test if the current session uses standard string literals.
2053  *
2054  * Note: With a pre-protocol-3.0 connection this will always say "false",
2055  * which should be the right answer.
2056  */
2057 bool
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 }
2072 
2073 
2074 /*
2075  * Return the session user of the current connection.
2076  *
2077  * Note: this will correctly detect the session user only with a
2078  * protocol-3.0 or newer backend; otherwise it will return the
2079  * connection user.
2080  */
2081 const char *
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 }
2095 
2096 
2097 /* expand_tilde
2098  *
2099  * substitute '~' with HOME or '~username' with username's home dir
2100  *
2101  */
2102 void
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 }
2153 
2154 /*
2155  * Checks if connection string starts with either of the valid URI prefix
2156  * designators.
2157  *
2158  * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
2159  *
2160  * XXX This is a duplicate of the eponymous libpq function.
2161  */
2162 static int
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 }
2179 
2180 /*
2181  * Recognized connection string either starts with a valid URI prefix or
2182  * contains a "=" in it.
2183  *
2184  * Must be consistent with parse_connection_string: anything for which this
2185  * returns true should at least look like it's parseable by that routine.
2186  *
2187  * XXX This is a duplicate of the eponymous libpq function.
2188  */
2189 bool
2191 {
2192  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
2193 }
static void PrintQueryStatus(PGresult *results)
Definition: common.c:1123
PSQL_ECHO echo
Definition: settings.h:131
bool singlestep
Definition: settings.h:127
char * gset_prefix
Definition: settings.h:95
char * extra
Definition: libpq-fe.h:165
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1155
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2681
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
volatile bool sigint_interrupt_enabled
Definition: common.c:273
int encoding
Definition: print.h:118
PsqlSettings pset
Definition: startup.c:33
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:557
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
static void error(void)
Definition: sql-dyntest.c:147
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:5899
PGnotify * PQnotifies(PGconn *conn)
Definition: fe-exec.c:2193
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2759
int PSQLexecWatch(const char *query, const printQueryOpt *opt)
Definition: common.c:697
void disable_sigpipe_trap(void)
Definition: print.c:2801
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
bool appendShellStringNoError(PQExpBuffer buf, const char *str)
Definition: string_utils.c:446
static bool ExecQueryTuples(const PGresult *result)
Definition: common.c:911
void ClosePager(FILE *pagerpipe)
Definition: print.c:2900
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:3635
static bool PrintQueryTuples(const PGresult *results)
Definition: common.c:812
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
bool recognized_connection_string(const char *connstr)
Definition: common.c:2190
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:199
Oid PQoidValue(const PGresult *res)
Definition: fe-exec.c:2985
struct timeval instr_time
Definition: instr_time.h:147
bool gexec_flag
Definition: settings.h:96
bool start_table
Definition: print.h:108
enum printFormat format
Definition: print.h:98
printTableOpt topt
Definition: print.h:165
static void PrintTiming(double elapsed_msec)
Definition: common.c:583
bool queryFoutPipe
Definition: settings.h:85
FILE * queryFout
Definition: settings.h:84
void set_sigpipe_trap_state(bool ignore)
Definition: print.c:2837
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3491
static bool CheckConnection(void)
Definition: common.c:406
return result
Definition: formatting.c:1618
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static bool ConnectionUp(void)
Definition: common.c:388
ExecStatusType
Definition: libpq-fe.h:82
char * inputfile
Definition: settings.h:108
bool on_error_stop
Definition: settings.h:124
bool autocommit
Definition: settings.h:123
#define lengthof(array)
Definition: c.h:562
int PQbinaryTuples(const PGresult *res)
Definition: fe-exec.c:2689
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
unsigned long prior_records
Definition: print.h:111
FILE * copyStream
Definition: settings.h:87
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
FILE * cur_cmd_source
Definition: settings.h:103
void UnsyncVariables(void)
Definition: command.c:3354
static bool AcceptResult(const PGresult *result)
Definition: common.c:505
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:5810
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:275
#define EXIT_BADCONN
Definition: settings.h:154
volatile bool cancel_pressed
Definition: print.c:46
static void PrintNotifications(void)
Definition: common.c:787
static int uri_prefix_length(const char *connstr)
Definition: common.c:2163
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
char * ctv_args[4]
Definition: settings.h:98
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3474
static int before(chr x, chr y)
Definition: regc_locale.c:496
unsigned short int expanded
Definition: print.h:99
bool cur_cmd_interactive
Definition: settings.h:105
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:132
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:2851
static bool is_select_command(const char *query)
Definition: common.c:1995
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:167
#define FALSE
Definition: c.h:221
int be_pid
Definition: libpq-fe.h:164
void expand_tilde(char **filename)
Definition: common.c:2103
#define MAXPGPATH
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static bool success
Definition: pg_basebackup.c:96
char * c
static char * buf
Definition: pg_test_fsync.c:66
const char * session_username(void)
Definition: common.c:2082
PGcancel * PQgetCancel(PGconn *conn)
Definition: fe-connect.c:3612
int fetch_count
Definition: settings.h:128
static bool ProcessResult(PGresult **results)
Definition: common.c:995
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
bool handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res)
Definition: copy.c:435
bool g_expanded
Definition: settings.h:94
bool PrintResultsInCrosstab(const PGresult *res)
Definition: crosstabview.c:103
const char *const days[]
Definition: datetime.c:69
void SetCancelConn(void)
Definition: common.c:445
char * relname
Definition: libpq-fe.h:163
#define write_stderr(str)
Definition: common.c:288
void restore_sigpipe_trap(void)
Definition: print.c:2824
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1496
void setup_cancel_handler(void)
Definition: common.c:331
PsqlScanQuoteType
Definition: psqlscan.h:52
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:5889
const char * GetVariable(VariableSpace space, const char *name)
Definition: variables.c:71
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2944
void psql_error(const char *fmt,...)
Definition: common.c:220
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:49
char * gfname
Definition: settings.h:93
bool setQFout(const char *fname)
Definition: common.c:84
static void cleanup(void)
Definition: bootstrap.c:855
PGresult * last_error_result
Definition: settings.h:89
FILE * logfile
Definition: settings.h:114
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:3468
bool stop_table
Definition: print.h:109
void PQclear(PGresult *res)
Definition: fe-exec.c:650
static void * fn(void *arg)
bool is_superuser(void)
Definition: common.c:2035
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
bool standard_strings(void)
Definition: common.c:2058
#define free(a)
Definition: header.h:65
static PGcancel *volatile cancelConn
Definition: common.c:277
void NoticeProcessor(void *arg, const char *message)
Definition: common.c:241
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
bool handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
Definition: copy.c:514
PGTransactionStatusType
Definition: libpq-fe.h:101
char * title
Definition: print.h:167
#define SIGNAL_ARGS
Definition: c.h:1079
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
const char * progname
Definition: settings.h:107
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
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:153
static const char short_uri_designator[]
Definition: fe-connect.c:332
char * psql_get_variable(const char *varname, PsqlScanQuoteType quote, void *passthrough)
Definition: common.c:128
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
Definition: fe-connect.c:3767
static char * filename
Definition: pg_dumpall.c:87
uint64 lineno
Definition: settings.h:109
static const char uri_designator[]
Definition: fe-connect.c:331
int i
const char * strerror(int errnum)
Definition: strerror.c:19
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:854
void html_escaped_print(const char *in, FILE *fout)
Definition: print.c:1745
bool crosstab_flag
Definition: settings.h:97
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
void * arg
bool SendQuery(const char *query)
Definition: common.c:1230
#define TRUE
Definition: c.h:217
static void handle_sigint(SIGNAL_ARGS)
Definition: common.c:300
static struct @121 value
int encoding
Definition: settings.h:83
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3092
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:5881
static bool command_no_begin(const char *query)
Definition: common.c:1796
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1184
typedef BOOL(WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess
void ResetCancelConn(void)
Definition: common.c:475
#define _(x)
Definition: elog.c:84
#define UINT64_FORMAT
Definition: c.h:316
void PQfreemem(void *ptr)
Definition: fe-exec.c:3200
long val
Definition: informix.c:689
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
static const char * skip_white_space(const char *query)
Definition: common.c:1732
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
void PQreset(PGconn *conn)
Definition: fe-connect.c:3505
bool get_home_path(char *ret_path)
Definition: path.c:807
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:642
VariableSpace vars
Definition: settings.h:116
static char * connstr
Definition: pg_dumpall.c:64