PostgreSQL Source Code  git master
common.c
Go to the documentation of this file.
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2022, PostgreSQL Global Development Group
5  *
6  * src/bin/psql/common.c
7  */
8 #include "postgres_fe.h"
9 
10 #include <ctype.h>
11 #include <limits.h>
12 #include <math.h>
13 #include <pwd.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 "command.h"
23 #include "common.h"
24 #include "common/logging.h"
25 #include "copy.h"
26 #include "crosstabview.h"
27 #include "fe_utils/cancel.h"
28 #include "fe_utils/mbprint.h"
29 #include "fe_utils/string_utils.h"
30 #include "portability/instr_time.h"
31 #include "settings.h"
32 
33 static bool DescribeQuery(const char *query, double *elapsed_msec);
34 static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec);
35 static int ExecQueryAndProcessResults(const char *query, double *elapsed_msec, bool *svpt_gone_p,
36  bool is_watch, const printQueryOpt *opt, FILE *printQueryFout);
37 static bool command_no_begin(const char *query);
38 static bool is_select_command(const char *query);
39 
40 
41 /*
42  * openQueryOutputFile --- attempt to open a query output file
43  *
44  * fname == NULL selects stdout, else an initial '|' selects a pipe,
45  * else plain file.
46  *
47  * Returns output file pointer into *fout, and is-a-pipe flag into *is_pipe.
48  * Caller is responsible for adjusting SIGPIPE state if it's a pipe.
49  *
50  * On error, reports suitable error message and returns false.
51  */
52 bool
53 openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
54 {
55  if (!fname || fname[0] == '\0')
56  {
57  *fout = stdout;
58  *is_pipe = false;
59  }
60  else if (*fname == '|')
61  {
62  *fout = popen(fname + 1, "w");
63  *is_pipe = true;
64  }
65  else
66  {
67  *fout = fopen(fname, "w");
68  *is_pipe = false;
69  }
70 
71  if (*fout == NULL)
72  {
73  pg_log_error("%s: %m", fname);
74  return false;
75  }
76 
77  return true;
78 }
79 
80 /*
81  * setQFout
82  * -- handler for -o command line option and \o command
83  *
84  * On success, updates pset with the new output file and returns true.
85  * On failure, returns false without changing pset state.
86  */
87 bool
88 setQFout(const char *fname)
89 {
90  FILE *fout;
91  bool is_pipe;
92 
93  /* First make sure we can open the new output file/pipe */
94  if (!openQueryOutputFile(fname, &fout, &is_pipe))
95  return false;
96 
97  /* Close old file/pipe */
98  if (pset.queryFout && pset.queryFout != stdout && pset.queryFout != stderr)
99  {
100  if (pset.queryFoutPipe)
101  pclose(pset.queryFout);
102  else
103  fclose(pset.queryFout);
104  }
105 
106  pset.queryFout = fout;
107  pset.queryFoutPipe = is_pipe;
108 
109  /* Adjust SIGPIPE handling appropriately: ignore signal if is_pipe */
110  set_sigpipe_trap_state(is_pipe);
112 
113  return true;
114 }
115 
116 
117 /*
118  * Variable-fetching callback for flex lexer
119  *
120  * If the specified variable exists, return its value as a string (malloc'd
121  * and expected to be freed by the caller); else return NULL.
122  *
123  * If "quote" isn't PQUOTE_PLAIN, then return the value suitably quoted and
124  * escaped for the specified quoting requirement. (Failure in escaping
125  * should lead to printing an error and returning NULL.)
126  *
127  * "passthrough" is the pointer previously given to psql_scan_set_passthrough.
128  * In psql, passthrough points to a ConditionalStack, which we check to
129  * determine whether variable expansion is allowed.
130  */
131 char *
132 psql_get_variable(const char *varname, PsqlScanQuoteType quote,
133  void *passthrough)
134 {
135  char *result = NULL;
136  const char *value;
137 
138  /* In an inactive \if branch, suppress all variable substitutions */
139  if (passthrough && !conditional_active((ConditionalStack) passthrough))
140  return NULL;
141 
142  value = GetVariable(pset.vars, varname);
143  if (!value)
144  return NULL;
145 
146  switch (quote)
147  {
148  case PQUOTE_PLAIN:
149  result = pg_strdup(value);
150  break;
151  case PQUOTE_SQL_LITERAL:
152  case PQUOTE_SQL_IDENT:
153  {
154  /*
155  * For these cases, we use libpq's quoting functions, which
156  * assume the string is in the connection's client encoding.
157  */
158  char *escaped_value;
159 
160  if (!pset.db)
161  {
162  pg_log_error("cannot escape without active connection");
163  return NULL;
164  }
165 
166  if (quote == PQUOTE_SQL_LITERAL)
167  escaped_value =
168  PQescapeLiteral(pset.db, value, strlen(value));
169  else
170  escaped_value =
171  PQescapeIdentifier(pset.db, value, strlen(value));
172 
173  if (escaped_value == NULL)
174  {
175  const char *error = PQerrorMessage(pset.db);
176 
177  pg_log_info("%s", error);
178  return NULL;
179  }
180 
181  /*
182  * Rather than complicate the lexer's API with a notion of
183  * which free() routine to use, just pay the price of an extra
184  * strdup().
185  */
186  result = pg_strdup(escaped_value);
187  PQfreemem(escaped_value);
188  break;
189  }
190  case PQUOTE_SHELL_ARG:
191  {
192  /*
193  * For this we use appendShellStringNoError, which is
194  * encoding-agnostic, which is fine since the shell probably
195  * is too. In any case, the only special character is "'",
196  * which is not known to appear in valid multibyte characters.
197  */
199 
202  {
203  pg_log_error("shell command argument contains a newline or carriage return: \"%s\"",
204  value);
205  free(buf.data);
206  return NULL;
207  }
208  result = buf.data;
209  break;
210  }
211 
212  /* No default: we want a compiler warning for missing cases */
213  }
214 
215  return result;
216 }
217 
218 
219 /*
220  * for backend Notice messages (INFO, WARNING, etc)
221  */
222 void
223 NoticeProcessor(void *arg, const char *message)
224 {
225  (void) arg; /* not used */
226  pg_log_info("%s", message);
227 }
228 
229 
230 
231 /*
232  * Code to support query cancellation
233  *
234  * Before we start a query, we enable the SIGINT signal catcher to send a
235  * cancel request to the backend.
236  *
237  * SIGINT is supposed to abort all long-running psql operations, not only
238  * database queries. In most places, this is accomplished by checking
239  * cancel_pressed during long-running loops. However, that won't work when
240  * blocked on user input (in readline() or fgets()). In those places, we
241  * set sigint_interrupt_enabled true while blocked, instructing the signal
242  * catcher to longjmp through sigint_interrupt_jmp. We assume readline and
243  * fgets are coded to handle possible interruption.
244  *
245  * On Windows, currently this does not work, so control-C is less useful
246  * there.
247  */
248 volatile bool sigint_interrupt_enabled = false;
249 
251 
252 static void
254 {
255 #ifndef WIN32
256  /* if we are waiting for input, longjmp out of it */
258  {
259  sigint_interrupt_enabled = false;
260  siglongjmp(sigint_interrupt_jmp, 1);
261  }
262 #endif
263 
264  /* else, set cancel flag to stop any long-running loops */
265  cancel_pressed = true;
266 }
267 
268 void
270 {
272 }
273 
274 
275 /* ConnectionUp
276  *
277  * Returns whether our backend connection is still there.
278  */
279 static bool
281 {
282  return PQstatus(pset.db) != CONNECTION_BAD;
283 }
284 
285 
286 
287 /* CheckConnection
288  *
289  * Verify that we still have a good connection to the backend, and if not,
290  * see if it can be restored.
291  *
292  * Returns true if either the connection was still there, or it could be
293  * restored successfully; false otherwise. If, however, there was no
294  * connection and the session is non-interactive, this will exit the program
295  * with a code of EXIT_BADCONN.
296  */
297 static bool
299 {
300  bool OK;
301 
302  OK = ConnectionUp();
303  if (!OK)
304  {
306  {
307  pg_log_error("connection to server was lost");
309  }
310 
311  fprintf(stderr, _("The connection to the server was lost. Attempting reset: "));
312  PQreset(pset.db);
313  OK = ConnectionUp();
314  if (!OK)
315  {
316  fprintf(stderr, _("Failed.\n"));
317 
318  /*
319  * Transition to having no connection; but stash away the failed
320  * connection so that we can still refer to its parameters in a
321  * later \connect attempt. Keep the state cleanup here in sync
322  * with do_connect().
323  */
324  if (pset.dead_conn)
326  pset.dead_conn = pset.db;
327  pset.db = NULL;
328  ResetCancelConn();
329  UnsyncVariables();
330  }
331  else
332  {
333  fprintf(stderr, _("Succeeded.\n"));
334 
335  /*
336  * Re-sync, just in case anything changed. Keep this in sync with
337  * do_connect().
338  */
339  SyncVariables();
340  connection_warnings(false); /* Must be after SyncVariables */
341  }
342  }
343 
344  return OK;
345 }
346 
347 
348 
349 
350 /*
351  * AcceptResult
352  *
353  * Checks whether a result is valid, giving an error message if necessary;
354  * and ensures that the connection to the backend is still up.
355  *
356  * Returns true for valid result, false for error state.
357  */
358 static bool
359 AcceptResult(const PGresult *result, bool show_error)
360 {
361  bool OK;
362 
363  if (!result)
364  OK = false;
365  else
366  switch (PQresultStatus(result))
367  {
368  case PGRES_COMMAND_OK:
369  case PGRES_TUPLES_OK:
370  case PGRES_EMPTY_QUERY:
371  case PGRES_COPY_IN:
372  case PGRES_COPY_OUT:
373  /* Fine, do nothing */
374  OK = true;
375  break;
376 
377  case PGRES_BAD_RESPONSE:
379  case PGRES_FATAL_ERROR:
380  OK = false;
381  break;
382 
383  default:
384  OK = false;
385  pg_log_error("unexpected PQresultStatus: %d",
386  PQresultStatus(result));
387  break;
388  }
389 
390  if (!OK && show_error)
391  {
392  const char *error = PQerrorMessage(pset.db);
393 
394  if (strlen(error))
395  pg_log_info("%s", error);
396 
397  CheckConnection();
398  }
399 
400  return OK;
401 }
402 
403 
404 /*
405  * Set special variables from a query result
406  * - ERROR: true/false, whether an error occurred on this query
407  * - SQLSTATE: code of error, or "00000" if no error, or "" if unknown
408  * - ROW_COUNT: how many rows were returned or affected, or "0"
409  * - LAST_ERROR_SQLSTATE: same for last error
410  * - LAST_ERROR_MESSAGE: message of last error
411  *
412  * Note: current policy is to apply this only to the results of queries
413  * entered by the user, not queries generated by slash commands.
414  */
415 static void
417 {
418  if (success)
419  {
420  const char *ntuples = PQcmdTuples(result);
421 
422  SetVariable(pset.vars, "ERROR", "false");
423  SetVariable(pset.vars, "SQLSTATE", "00000");
424  SetVariable(pset.vars, "ROW_COUNT", *ntuples ? ntuples : "0");
425  }
426  else
427  {
428  const char *code = PQresultErrorField(result, PG_DIAG_SQLSTATE);
429  const char *mesg = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
430 
431  SetVariable(pset.vars, "ERROR", "true");
432 
433  /*
434  * If there is no SQLSTATE code, use an empty string. This can happen
435  * for libpq-detected errors (e.g., lost connection, ENOMEM).
436  */
437  if (code == NULL)
438  code = "";
439  SetVariable(pset.vars, "SQLSTATE", code);
440  SetVariable(pset.vars, "ROW_COUNT", "0");
441  SetVariable(pset.vars, "LAST_ERROR_SQLSTATE", code);
442  SetVariable(pset.vars, "LAST_ERROR_MESSAGE", mesg ? mesg : "");
443  }
444 }
445 
446 
447 /*
448  * ClearOrSaveResult
449  *
450  * If the result represents an error, remember it for possible display by
451  * \errverbose. Otherwise, just PQclear() it.
452  *
453  * Note: current policy is to apply this to the results of all queries,
454  * including "back door" queries, for debugging's sake. It's OK to use
455  * PQclear() directly on results known to not be error results, however.
456  */
457 static void
459 {
460  if (result)
461  {
462  switch (PQresultStatus(result))
463  {
465  case PGRES_FATAL_ERROR:
467  pset.last_error_result = result;
468  break;
469 
470  default:
471  PQclear(result);
472  break;
473  }
474  }
475 }
476 
477 
478 /*
479  * Consume all results
480  */
481 static void
483 {
484  PGresult *result;
485 
486  while ((result = PQgetResult(pset.db)) != NULL)
487  ClearOrSaveResult(result);
488 }
489 
490 
491 /*
492  * Print microtiming output. Always print raw milliseconds; if the interval
493  * is >= 1 second, also break it down into days/hours/minutes/seconds.
494  */
495 static void
496 PrintTiming(double elapsed_msec)
497 {
498  double seconds;
499  double minutes;
500  double hours;
501  double days;
502 
503  if (elapsed_msec < 1000.0)
504  {
505  /* This is the traditional (pre-v10) output format */
506  printf(_("Time: %.3f ms\n"), elapsed_msec);
507  return;
508  }
509 
510  /*
511  * Note: we could print just seconds, in a format like %06.3f, when the
512  * total is less than 1min. But that's hard to interpret unless we tack
513  * on "s" or otherwise annotate it. Forcing the display to include
514  * minutes seems like a better solution.
515  */
516  seconds = elapsed_msec / 1000.0;
517  minutes = floor(seconds / 60.0);
518  seconds -= 60.0 * minutes;
519  if (minutes < 60.0)
520  {
521  printf(_("Time: %.3f ms (%02d:%06.3f)\n"),
522  elapsed_msec, (int) minutes, seconds);
523  return;
524  }
525 
526  hours = floor(minutes / 60.0);
527  minutes -= 60.0 * hours;
528  if (hours < 24.0)
529  {
530  printf(_("Time: %.3f ms (%02d:%02d:%06.3f)\n"),
531  elapsed_msec, (int) hours, (int) minutes, seconds);
532  return;
533  }
534 
535  days = floor(hours / 24.0);
536  hours -= 24.0 * days;
537  printf(_("Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n"),
538  elapsed_msec, days, (int) hours, (int) minutes, seconds);
539 }
540 
541 
542 /*
543  * PSQLexec
544  *
545  * This is the way to send "backdoor" queries (those not directly entered
546  * by the user). It is subject to -E but not -e.
547  *
548  * Caller is responsible for handling the ensuing processing if a COPY
549  * command is sent.
550  *
551  * Note: we don't bother to check PQclientEncoding; it is assumed that no
552  * caller uses this path to issue "SET CLIENT_ENCODING".
553  */
554 PGresult *
555 PSQLexec(const char *query)
556 {
557  PGresult *res;
558 
559  if (!pset.db)
560  {
561  pg_log_error("You are currently not connected to a database.");
562  return NULL;
563  }
564 
566  {
567  printf(_("********* QUERY **********\n"
568  "%s\n"
569  "**************************\n\n"), query);
570  fflush(stdout);
571  if (pset.logfile)
572  {
574  _("********* QUERY **********\n"
575  "%s\n"
576  "**************************\n\n"), query);
578  }
579 
581  return NULL;
582  }
583 
585 
586  res = PQexec(pset.db, query);
587 
588  ResetCancelConn();
589 
590  if (!AcceptResult(res, true))
591  {
593  res = NULL;
594  }
595 
596  return res;
597 }
598 
599 
600 /*
601  * PSQLexecWatch
602  *
603  * This function is used for \watch command to send the query to
604  * the server and print out the result.
605  *
606  * Returns 1 if the query executed successfully, 0 if it cannot be repeated,
607  * e.g., because of the interrupt, -1 on error.
608  */
609 int
610 PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout)
611 {
612  bool timing = pset.timing;
613  double elapsed_msec = 0;
614  int res;
615 
616  if (!pset.db)
617  {
618  pg_log_error("You are currently not connected to a database.");
619  return 0;
620  }
621 
623 
624  res = ExecQueryAndProcessResults(query, &elapsed_msec, NULL, true, opt, printQueryFout);
625 
626  ResetCancelConn();
627 
628  /* Possible microtiming output */
629  if (timing)
630  PrintTiming(elapsed_msec);
631 
632  return res;
633 }
634 
635 
636 /*
637  * PrintNotifications: check for asynchronous notifications, and print them out
638  */
639 static void
641 {
642  PGnotify *notify;
643 
645  while ((notify = PQnotifies(pset.db)) != NULL)
646  {
647  /* for backward compatibility, only show payload if nonempty */
648  if (notify->extra[0])
649  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
650  notify->relname, notify->extra, notify->be_pid);
651  else
652  fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
653  notify->relname, notify->be_pid);
655  PQfreemem(notify);
657  }
658 }
659 
660 
661 /*
662  * PrintQueryTuples: assuming query result is OK, print its tuples
663  *
664  * Returns true if successful, false otherwise.
665  */
666 static bool
667 PrintQueryTuples(const PGresult *result, const printQueryOpt *opt, FILE *printQueryFout)
668 {
669  bool ok = true;
670 
671  /* write output to \g argument, if any */
672  if (pset.gfname)
673  {
674  FILE *fout;
675  bool is_pipe;
676 
677  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
678  return false;
679  if (is_pipe)
681 
682  printQuery(result, &pset.popt, fout, false, pset.logfile);
683  if (ferror(fout))
684  {
685  pg_log_error("could not print result table: %m");
686  ok = false;
687  }
688 
689  if (is_pipe)
690  {
691  pclose(fout);
693  }
694  else
695  fclose(fout);
696  }
697  else
698  {
699  FILE *fout = printQueryFout ? printQueryFout : pset.queryFout;
700 
701  printQuery(result, opt ? opt : &pset.popt, fout, false, pset.logfile);
702  if (ferror(fout))
703  {
704  pg_log_error("could not print result table: %m");
705  ok = false;
706  }
707  }
708 
709  return ok;
710 }
711 
712 
713 /*
714  * StoreQueryTuple: assuming query result is OK, save data into variables
715  *
716  * Returns true if successful, false otherwise.
717  */
718 static bool
719 StoreQueryTuple(const PGresult *result)
720 {
721  bool success = true;
722 
723  if (PQntuples(result) < 1)
724  {
725  pg_log_error("no rows returned for \\gset");
726  success = false;
727  }
728  else if (PQntuples(result) > 1)
729  {
730  pg_log_error("more than one row returned for \\gset");
731  success = false;
732  }
733  else
734  {
735  int i;
736 
737  for (i = 0; i < PQnfields(result); i++)
738  {
739  char *colname = PQfname(result, i);
740  char *varname;
741  char *value;
742 
743  /* concatenate prefix and column name */
744  varname = psprintf("%s%s", pset.gset_prefix, colname);
745 
746  if (VariableHasHook(pset.vars, varname))
747  {
748  pg_log_warning("attempt to \\gset into specially treated variable \"%s\" ignored",
749  varname);
750  continue;
751  }
752 
753  if (!PQgetisnull(result, 0, i))
754  value = PQgetvalue(result, 0, i);
755  else
756  {
757  /* for NULL value, unset rather than set the variable */
758  value = NULL;
759  }
760 
761  if (!SetVariable(pset.vars, varname, value))
762  {
763  free(varname);
764  success = false;
765  break;
766  }
767 
768  free(varname);
769  }
770  }
771 
772  return success;
773 }
774 
775 
776 /*
777  * ExecQueryTuples: assuming query result is OK, execute each query
778  * result field as a SQL statement
779  *
780  * Returns true if successful, false otherwise.
781  */
782 static bool
783 ExecQueryTuples(const PGresult *result)
784 {
785  bool success = true;
786  int nrows = PQntuples(result);
787  int ncolumns = PQnfields(result);
788  int r,
789  c;
790 
791  /*
792  * We must turn off gexec_flag to avoid infinite recursion. Note that
793  * this allows ExecQueryUsingCursor to be applied to the individual query
794  * results. SendQuery prevents it from being applied when fetching the
795  * queries-to-execute, because it can't handle recursion either.
796  */
797  pset.gexec_flag = false;
798 
799  for (r = 0; r < nrows; r++)
800  {
801  for (c = 0; c < ncolumns; c++)
802  {
803  if (!PQgetisnull(result, r, c))
804  {
805  const char *query = PQgetvalue(result, r, c);
806 
807  /* Abandon execution if cancel_pressed */
808  if (cancel_pressed)
809  goto loop_exit;
810 
811  /*
812  * ECHO_ALL mode should echo these queries, but SendQuery
813  * assumes that MainLoop did that, so we have to do it here.
814  */
816  {
817  puts(query);
818  fflush(stdout);
819  }
820 
821  if (!SendQuery(query))
822  {
823  /* Error - abandon execution if ON_ERROR_STOP */
824  success = false;
825  if (pset.on_error_stop)
826  goto loop_exit;
827  }
828  }
829  }
830  }
831 
832 loop_exit:
833 
834  /*
835  * Restore state. We know gexec_flag was on, else we'd not be here. (We
836  * also know it'll get turned off at end of command, but that's not ours
837  * to do here.)
838  */
839  pset.gexec_flag = true;
840 
841  /* Return true if all queries were successful */
842  return success;
843 }
844 
845 
846 /*
847  * Marshal the COPY data. Either subroutine will get the
848  * connection out of its COPY state, then call PQresultStatus()
849  * once and report any error. Return whether all was ok.
850  *
851  * For COPY OUT, direct the output to pset.copyStream if it's set,
852  * otherwise to pset.gfname if it's set, otherwise to queryFout.
853  * For COPY IN, use pset.copyStream as data source if it's set,
854  * otherwise cur_cmd_source.
855  *
856  * Update result if further processing is necessary, or NULL otherwise.
857  * Return a result when queryFout can safely output a result status: on COPY
858  * IN, or on COPY OUT if written to something other than pset.queryFout.
859  * Returning NULL prevents the command status from being printed, which we
860  * want if the status line doesn't get taken as part of the COPY data.
861  */
862 static bool
864 {
865  bool success;
866  FILE *copystream;
867  PGresult *copy_result;
868  ExecStatusType result_status = PQresultStatus(*resultp);
869 
870  Assert(result_status == PGRES_COPY_OUT ||
871  result_status == PGRES_COPY_IN);
872 
874 
875  if (result_status == PGRES_COPY_OUT)
876  {
877  bool need_close = false;
878  bool is_pipe = false;
879 
880  if (pset.copyStream)
881  {
882  /* invoked by \copy */
883  copystream = pset.copyStream;
884  }
885  else if (pset.gfname)
886  {
887  /* invoked by \g */
889  &copystream, &is_pipe))
890  {
891  need_close = true;
892  if (is_pipe)
894  }
895  else
896  copystream = NULL; /* discard COPY data entirely */
897  }
898  else
899  {
900  /* fall back to the generic query output stream */
901  copystream = pset.queryFout;
902  }
903 
905  copystream,
906  &copy_result)
907  && (copystream != NULL);
908 
909  /*
910  * Suppress status printing if the report would go to the same place
911  * as the COPY data just went. Note this doesn't prevent error
912  * reporting, since handleCopyOut did that.
913  */
914  if (copystream == pset.queryFout)
915  {
916  PQclear(copy_result);
917  copy_result = NULL;
918  }
919 
920  if (need_close)
921  {
922  /* close \g argument file/pipe */
923  if (is_pipe)
924  {
925  pclose(copystream);
927  }
928  else
929  {
930  fclose(copystream);
931  }
932  }
933  }
934  else
935  {
936  /* COPY IN */
939  copystream,
940  PQbinaryTuples(*resultp),
941  &copy_result);
942  }
943  ResetCancelConn();
944 
945  /*
946  * Replace the PGRES_COPY_OUT/IN result with COPY command's exit status,
947  * or with NULL if we want to suppress printing anything.
948  */
949  PQclear(*resultp);
950  *resultp = copy_result;
951 
952  return success;
953 }
954 
955 /*
956  * PrintQueryStatus: report command status as required
957  *
958  * Note: Utility function for use by PrintQueryResult() only.
959  */
960 static void
961 PrintQueryStatus(PGresult *result, FILE *printQueryFout)
962 {
963  char buf[16];
964  FILE *fout = printQueryFout ? printQueryFout : pset.queryFout;
965 
966  if (!pset.quiet)
967  {
968  if (pset.popt.topt.format == PRINT_HTML)
969  {
970  fputs("<p>", fout);
971  html_escaped_print(PQcmdStatus(result), fout);
972  fputs("</p>\n", fout);
973  }
974  else
975  fprintf(fout, "%s\n", PQcmdStatus(result));
976  }
977 
978  if (pset.logfile)
979  fprintf(pset.logfile, "%s\n", PQcmdStatus(result));
980 
981  snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(result));
982  SetVariable(pset.vars, "LASTOID", buf);
983 }
984 
985 
986 /*
987  * PrintQueryResult: print out (or store or execute) query result as required
988  *
989  * Note: Utility function for use by SendQuery() only.
990  *
991  * Returns true if the query executed successfully, false otherwise.
992  */
993 static bool
994 PrintQueryResult(PGresult *result, bool last, bool is_watch, const printQueryOpt *opt, FILE *printQueryFout)
995 {
996  bool success;
997  const char *cmdstatus;
998 
999  if (!result)
1000  return false;
1001 
1002  switch (PQresultStatus(result))
1003  {
1004  case PGRES_TUPLES_OK:
1005  /* store or execute or print the data ... */
1006  if (last && pset.gset_prefix)
1007  success = StoreQueryTuple(result);
1008  else if (last && pset.gexec_flag)
1009  success = ExecQueryTuples(result);
1010  else if (last && pset.crosstab_flag)
1011  success = PrintResultInCrosstab(result);
1012  else if (last || pset.show_all_results)
1013  success = PrintQueryTuples(result, opt, printQueryFout);
1014  else
1015  success = true;
1016 
1017  /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
1018  if (last || pset.show_all_results)
1019  {
1020  cmdstatus = PQcmdStatus(result);
1021  if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
1022  strncmp(cmdstatus, "UPDATE", 6) == 0 ||
1023  strncmp(cmdstatus, "DELETE", 6) == 0)
1024  PrintQueryStatus(result, printQueryFout);
1025  }
1026 
1027  break;
1028 
1029  case PGRES_COMMAND_OK:
1030  if (last || pset.show_all_results)
1031  PrintQueryStatus(result, printQueryFout);
1032  success = true;
1033  break;
1034 
1035  case PGRES_EMPTY_QUERY:
1036  success = true;
1037  break;
1038 
1039  case PGRES_COPY_OUT:
1040  case PGRES_COPY_IN:
1041  /* nothing to do here: already processed */
1042  success = true;
1043  break;
1044 
1045  case PGRES_BAD_RESPONSE:
1046  case PGRES_NONFATAL_ERROR:
1047  case PGRES_FATAL_ERROR:
1048  success = false;
1049  break;
1050 
1051  default:
1052  success = false;
1053  pg_log_error("unexpected PQresultStatus: %d",
1054  PQresultStatus(result));
1055  break;
1056  }
1057 
1058  fflush(printQueryFout ? printQueryFout : pset.queryFout);
1059 
1060  return success;
1061 }
1062 
1063 /*
1064  * SendQuery: send the query string to the backend
1065  * (and print out result)
1066  *
1067  * Note: This is the "front door" way to send a query. That is, use it to
1068  * send queries actually entered by the user. These queries will be subject to
1069  * single step mode.
1070  * To send "back door" queries (generated by slash commands, etc.) in a
1071  * controlled way, use PSQLexec().
1072  *
1073  * Returns true if the query executed successfully, false otherwise.
1074  */
1075 bool
1076 SendQuery(const char *query)
1077 {
1078  bool timing = pset.timing;
1079  PGTransactionStatusType transaction_status;
1080  double elapsed_msec = 0;
1081  bool OK = false;
1082  int i;
1083  bool on_error_rollback_savepoint = false;
1084  bool svpt_gone = false;
1085 
1086  if (!pset.db)
1087  {
1088  pg_log_error("You are currently not connected to a database.");
1089  goto sendquery_cleanup;
1090  }
1091 
1092  if (pset.singlestep)
1093  {
1094  char buf[3];
1095 
1096  fflush(stderr);
1097  printf(_("***(Single step mode: verify command)*******************************************\n"
1098  "%s\n"
1099  "***(press return to proceed or enter x and return to cancel)********************\n"),
1100  query);
1101  fflush(stdout);
1102  if (fgets(buf, sizeof(buf), stdin) != NULL)
1103  if (buf[0] == 'x')
1104  goto sendquery_cleanup;
1105  if (cancel_pressed)
1106  goto sendquery_cleanup;
1107  }
1108  else if (pset.echo == PSQL_ECHO_QUERIES)
1109  {
1110  puts(query);
1111  fflush(stdout);
1112  }
1113 
1114  if (pset.logfile)
1115  {
1117  _("********* QUERY **********\n"
1118  "%s\n"
1119  "**************************\n\n"), query);
1120  fflush(pset.logfile);
1121  }
1122 
1124 
1125  transaction_status = PQtransactionStatus(pset.db);
1126 
1127  if (transaction_status == PQTRANS_IDLE &&
1128  !pset.autocommit &&
1129  !command_no_begin(query))
1130  {
1131  PGresult *result;
1132 
1133  result = PQexec(pset.db, "BEGIN");
1134  if (PQresultStatus(result) != PGRES_COMMAND_OK)
1135  {
1137  ClearOrSaveResult(result);
1138  goto sendquery_cleanup;
1139  }
1140  ClearOrSaveResult(result);
1141  transaction_status = PQtransactionStatus(pset.db);
1142  }
1143 
1144  if (transaction_status == PQTRANS_INTRANS &&
1148  {
1149  PGresult *result;
1150 
1151  result = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
1152  if (PQresultStatus(result) != PGRES_COMMAND_OK)
1153  {
1155  ClearOrSaveResult(result);
1156  goto sendquery_cleanup;
1157  }
1158  ClearOrSaveResult(result);
1159  on_error_rollback_savepoint = true;
1160  }
1161 
1162  if (pset.gdesc_flag)
1163  {
1164  /* Describe query's result columns, without executing it */
1165  OK = DescribeQuery(query, &elapsed_msec);
1166  }
1167  else if (pset.fetch_count <= 0 || pset.gexec_flag ||
1169  {
1170  /* Default fetch-it-all-and-print mode */
1171  OK = (ExecQueryAndProcessResults(query, &elapsed_msec, &svpt_gone, false, NULL, NULL) >= 0);
1172  }
1173  else
1174  {
1175  /* Fetch-in-segments mode */
1176  OK = ExecQueryUsingCursor(query, &elapsed_msec);
1177  }
1178 
1179  if (!OK && pset.echo == PSQL_ECHO_ERRORS)
1180  pg_log_info("STATEMENT: %s", query);
1181 
1182  /* If we made a temporary savepoint, possibly release/rollback */
1183  if (on_error_rollback_savepoint)
1184  {
1185  const char *svptcmd = NULL;
1186 
1187  transaction_status = PQtransactionStatus(pset.db);
1188 
1189  switch (transaction_status)
1190  {
1191  case PQTRANS_INERROR:
1192  /* We always rollback on an error */
1193  svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
1194  break;
1195 
1196  case PQTRANS_IDLE:
1197  /* If they are no longer in a transaction, then do nothing */
1198  break;
1199 
1200  case PQTRANS_INTRANS:
1201 
1202  /*
1203  * Release our savepoint, but do nothing if they are messing
1204  * with savepoints themselves
1205  */
1206  if (!svpt_gone)
1207  svptcmd = "RELEASE pg_psql_temporary_savepoint";
1208  break;
1209 
1210  case PQTRANS_ACTIVE:
1211  case PQTRANS_UNKNOWN:
1212  default:
1213  OK = false;
1214  /* PQTRANS_UNKNOWN is expected given a broken connection. */
1215  if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp())
1216  pg_log_error("unexpected transaction status (%d)",
1217  transaction_status);
1218  break;
1219  }
1220 
1221  if (svptcmd)
1222  {
1223  PGresult *svptres;
1224 
1225  svptres = PQexec(pset.db, svptcmd);
1226  if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
1227  {
1229  ClearOrSaveResult(svptres);
1230  OK = false;
1231 
1232  goto sendquery_cleanup;
1233  }
1234  PQclear(svptres);
1235  }
1236  }
1237 
1238  /* Possible microtiming output */
1239  if (timing)
1240  PrintTiming(elapsed_msec);
1241 
1242  /* check for events that may occur during query execution */
1243 
1244  if (pset.encoding != PQclientEncoding(pset.db) &&
1245  PQclientEncoding(pset.db) >= 0)
1246  {
1247  /* track effects of SET CLIENT_ENCODING */
1250  SetVariable(pset.vars, "ENCODING",
1252  }
1253 
1255 
1256  /* perform cleanup that should occur after any attempted query */
1257 
1258 sendquery_cleanup:
1259 
1260  /* global cancellation reset */
1261  ResetCancelConn();
1262 
1263  /* reset \g's output-to-filename trigger */
1264  if (pset.gfname)
1265  {
1266  free(pset.gfname);
1267  pset.gfname = NULL;
1268  }
1269 
1270  /* restore print settings if \g changed them */
1271  if (pset.gsavepopt)
1272  {
1274  pset.gsavepopt = NULL;
1275  }
1276 
1277  /* reset \gset trigger */
1278  if (pset.gset_prefix)
1279  {
1281  pset.gset_prefix = NULL;
1282  }
1283 
1284  /* reset \gdesc trigger */
1285  pset.gdesc_flag = false;
1286 
1287  /* reset \gexec trigger */
1288  pset.gexec_flag = false;
1289 
1290  /* reset \crosstabview trigger */
1291  pset.crosstab_flag = false;
1292  for (i = 0; i < lengthof(pset.ctv_args); i++)
1293  {
1294  pg_free(pset.ctv_args[i]);
1295  pset.ctv_args[i] = NULL;
1296  }
1297 
1298  return OK;
1299 }
1300 
1301 
1302 /*
1303  * DescribeQuery: describe the result columns of a query, without executing it
1304  *
1305  * Returns true if the operation executed successfully, false otherwise.
1306  *
1307  * If pset.timing is on, total query time (exclusive of result-printing) is
1308  * stored into *elapsed_msec.
1309  */
1310 static bool
1311 DescribeQuery(const char *query, double *elapsed_msec)
1312 {
1313  bool timing = pset.timing;
1314  PGresult *result;
1315  bool OK;
1317  after;
1318 
1319  *elapsed_msec = 0;
1320 
1321  if (timing)
1323 
1324  /*
1325  * To parse the query but not execute it, we prepare it, using the unnamed
1326  * prepared statement. This is invisible to psql users, since there's no
1327  * way to access the unnamed prepared statement from psql user space. The
1328  * next Parse or Query protocol message would overwrite the statement
1329  * anyway. (So there's no great need to clear it when done, which is a
1330  * good thing because libpq provides no easy way to do that.)
1331  */
1332  result = PQprepare(pset.db, "", query, 0, NULL);
1333  if (PQresultStatus(result) != PGRES_COMMAND_OK)
1334  {
1336  SetResultVariables(result, false);
1337  ClearOrSaveResult(result);
1338  return false;
1339  }
1340  PQclear(result);
1341 
1342  result = PQdescribePrepared(pset.db, "");
1343  OK = AcceptResult(result, true) &&
1344  (PQresultStatus(result) == PGRES_COMMAND_OK);
1345  if (OK && result)
1346  {
1347  if (PQnfields(result) > 0)
1348  {
1350  int i;
1351 
1352  initPQExpBuffer(&buf);
1353 
1355  "SELECT name AS \"%s\", pg_catalog.format_type(tp, tpm) AS \"%s\"\n"
1356  "FROM (VALUES ",
1357  gettext_noop("Column"),
1358  gettext_noop("Type"));
1359 
1360  for (i = 0; i < PQnfields(result); i++)
1361  {
1362  const char *name;
1363  char *escname;
1364 
1365  if (i > 0)
1366  appendPQExpBufferStr(&buf, ",");
1367 
1368  name = PQfname(result, i);
1369  escname = PQescapeLiteral(pset.db, name, strlen(name));
1370 
1371  if (escname == NULL)
1372  {
1374  PQclear(result);
1375  termPQExpBuffer(&buf);
1376  return false;
1377  }
1378 
1379  appendPQExpBuffer(&buf, "(%s, '%u'::pg_catalog.oid, %d)",
1380  escname,
1381  PQftype(result, i),
1382  PQfmod(result, i));
1383 
1384  PQfreemem(escname);
1385  }
1386 
1387  appendPQExpBufferStr(&buf, ") s(name, tp, tpm)");
1388  PQclear(result);
1389 
1390  result = PQexec(pset.db, buf.data);
1391  OK = AcceptResult(result, true);
1392 
1393  if (timing)
1394  {
1395  INSTR_TIME_SET_CURRENT(after);
1396  INSTR_TIME_SUBTRACT(after, before);
1397  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1398  }
1399 
1400  if (OK && result)
1401  OK = PrintQueryResult(result, true, false, NULL, NULL);
1402 
1403  termPQExpBuffer(&buf);
1404  }
1405  else
1407  _("The command has no result, or the result has no columns.\n"));
1408  }
1409 
1410  SetResultVariables(result, OK);
1411  ClearOrSaveResult(result);
1412 
1413  return OK;
1414 }
1415 
1416 
1417 /*
1418  * ExecQueryAndProcessResults: utility function for use by SendQuery()
1419  * and PSQLexecWatch().
1420  *
1421  * Sends query and cycles through PGresult objects.
1422  *
1423  * When not under \watch and if our command string contained a COPY FROM STDIN
1424  * or COPY TO STDOUT, the PGresult associated with these commands must be
1425  * processed by providing an input or output stream. In that event, we'll
1426  * marshal data for the COPY.
1427  *
1428  * For other commands, the results are processed normally, depending on their
1429  * status.
1430  *
1431  * Returns 1 on complete success, 0 on interrupt and -1 or errors. Possible
1432  * failure modes include purely client-side problems; check the transaction
1433  * status for the server-side opinion.
1434  *
1435  * Note that on a combined query, failure does not mean that nothing was
1436  * committed.
1437  */
1438 static int
1439 ExecQueryAndProcessResults(const char *query, double *elapsed_msec, bool *svpt_gone_p,
1440  bool is_watch, const printQueryOpt *opt, FILE *printQueryFout)
1441 {
1442  bool timing = pset.timing;
1443  bool success;
1445  after;
1446  PGresult *result;
1447 
1448  if (timing)
1450 
1451  success = PQsendQuery(pset.db, query);
1452 
1453  if (!success)
1454  {
1455  const char *error = PQerrorMessage(pset.db);
1456 
1457  if (strlen(error))
1458  pg_log_info("%s", error);
1459 
1460  CheckConnection();
1461 
1462  return -1;
1463  }
1464 
1465  /*
1466  * If SIGINT is sent while the query is processing, the interrupt will be
1467  * consumed. The user's intention, though, is to cancel the entire watch
1468  * process, so detect a sent cancellation request and exit in this case.
1469  */
1470  if (is_watch && cancel_pressed)
1471  {
1473  return 0;
1474  }
1475 
1476  /* first result */
1477  result = PQgetResult(pset.db);
1478 
1479  while (result != NULL)
1480  {
1481  ExecStatusType result_status;
1482  PGresult *next_result;
1483  bool last;
1484 
1485  if (!AcceptResult(result, false))
1486  {
1487  /*
1488  * Some error occured, either a server-side failure or a failure
1489  * to submit the command string. Record that.
1490  */
1491  const char *error = PQresultErrorMessage(result);
1492 
1493  if (strlen(error))
1494  pg_log_info("%s", error);
1495 
1496  CheckConnection();
1497  if (!is_watch)
1498  SetResultVariables(result, false);
1499 
1500  /* keep the result status before clearing it */
1501  result_status = PQresultStatus(result);
1502  ClearOrSaveResult(result);
1503  success = false;
1504 
1505  /*
1506  * switch to next result
1507  */
1508  if (result_status == PGRES_COPY_BOTH ||
1509  result_status == PGRES_COPY_OUT ||
1510  result_status == PGRES_COPY_IN)
1511 
1512  /*
1513  * For some obscure reason PQgetResult does *not* return a
1514  * NULL in copy cases despite the result having been cleared,
1515  * but keeps returning an "empty" result that we have to
1516  * ignore manually.
1517  */
1518  result = NULL;
1519  else
1520  result = PQgetResult(pset.db);
1521 
1522  /*
1523  * Get current timing measure in case an error occurs
1524  */
1525  if (timing)
1526  {
1527  INSTR_TIME_SET_CURRENT(after);
1528  INSTR_TIME_SUBTRACT(after, before);
1529  *elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1530  }
1531 
1532  continue;
1533  }
1534  else if (svpt_gone_p && !*svpt_gone_p)
1535  {
1536  /*
1537  * Check if the user ran any command that would destroy our
1538  * internal savepoint: If the user did COMMIT AND CHAIN, RELEASE
1539  * or ROLLBACK, our savepoint is gone. If they issued a SAVEPOINT,
1540  * releasing ours would remove theirs.
1541  */
1542  const char *cmd = PQcmdStatus(result);
1543 
1544  *svpt_gone_p = (strcmp(cmd, "COMMIT") == 0 ||
1545  strcmp(cmd, "SAVEPOINT") == 0 ||
1546  strcmp(cmd, "RELEASE") == 0 ||
1547  strcmp(cmd, "ROLLBACK") == 0);
1548  }
1549 
1550  result_status = PQresultStatus(result);
1551 
1552  /* must handle COPY before changing the current result */
1553  Assert(result_status != PGRES_COPY_BOTH);
1554  if (result_status == PGRES_COPY_IN ||
1555  result_status == PGRES_COPY_OUT)
1556  {
1557  if (is_watch)
1558  {
1560  pg_log_error("\\watch cannot be used with COPY");
1561  return -1;
1562  }
1563 
1564  success &= HandleCopyResult(&result);
1565  }
1566 
1567  /*
1568  * Check PQgetResult() again. In the typical case of a single-command
1569  * string, it will return NULL. Otherwise, we'll have other results
1570  * to process. We need to do that to check whether this is the last.
1571  */
1572  next_result = PQgetResult(pset.db);
1573  last = (next_result == NULL);
1574 
1575  /*
1576  * Update current timing measure.
1577  *
1578  * It will include the display of previous results, if any. This
1579  * cannot be helped because the server goes on processing further
1580  * queries anyway while the previous ones are being displayed. The
1581  * parallel execution of the client display hides the server time when
1582  * it is shorter.
1583  *
1584  * With combined queries, timing must be understood as an upper bound
1585  * of the time spent processing them.
1586  */
1587  if (timing)
1588  {
1589  INSTR_TIME_SET_CURRENT(after);
1590  INSTR_TIME_SUBTRACT(after, before);
1591  *elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1592  }
1593 
1594  /* this may or may not print something depending on settings */
1595  if (result != NULL)
1596  success &= PrintQueryResult(result, last, false, opt, printQueryFout);
1597 
1598  /* set variables on last result if all went well */
1599  if (!is_watch && last && success)
1600  SetResultVariables(result, true);
1601 
1602  ClearOrSaveResult(result);
1603  result = next_result;
1604 
1605  if (cancel_pressed)
1606  {
1608  break;
1609  }
1610  }
1611 
1612  /* may need this to recover from conn loss during COPY */
1613  if (!CheckConnection())
1614  return -1;
1615 
1616  return cancel_pressed ? 0 : success ? 1 : -1;
1617 }
1618 
1619 
1620 /*
1621  * ExecQueryUsingCursor: run a SELECT-like query using a cursor
1622  *
1623  * This feature allows result sets larger than RAM to be dealt with.
1624  *
1625  * Returns true if the query executed successfully, false otherwise.
1626  *
1627  * If pset.timing is on, total query time (exclusive of result-printing) is
1628  * stored into *elapsed_msec.
1629  */
1630 static bool
1631 ExecQueryUsingCursor(const char *query, double *elapsed_msec)
1632 {
1633  bool OK = true;
1634  PGresult *result;
1636  printQueryOpt my_popt = pset.popt;
1637  bool timing = pset.timing;
1638  FILE *fout;
1639  bool is_pipe;
1640  bool is_pager = false;
1641  bool started_txn = false;
1642  int64 total_tuples = 0;
1643  int ntuples;
1644  int fetch_count;
1645  char fetch_cmd[64];
1647  after;
1648  int flush_error;
1649 
1650  *elapsed_msec = 0;
1651 
1652  /* initialize print options for partial table output */
1653  my_popt.topt.start_table = true;
1654  my_popt.topt.stop_table = false;
1655  my_popt.topt.prior_records = 0;
1656 
1657  if (timing)
1659 
1660  /* if we're not in a transaction, start one */
1662  {
1663  result = PQexec(pset.db, "BEGIN");
1664  OK = AcceptResult(result, true) &&
1665  (PQresultStatus(result) == PGRES_COMMAND_OK);
1666  ClearOrSaveResult(result);
1667  if (!OK)
1668  return false;
1669  started_txn = true;
1670  }
1671 
1672  /* Send DECLARE CURSOR */
1673  initPQExpBuffer(&buf);
1674  appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1675  query);
1676 
1677  result = PQexec(pset.db, buf.data);
1678  OK = AcceptResult(result, true) &&
1679  (PQresultStatus(result) == PGRES_COMMAND_OK);
1680  if (!OK)
1681  SetResultVariables(result, OK);
1682  ClearOrSaveResult(result);
1683  termPQExpBuffer(&buf);
1684  if (!OK)
1685  goto cleanup;
1686 
1687  if (timing)
1688  {
1689  INSTR_TIME_SET_CURRENT(after);
1690  INSTR_TIME_SUBTRACT(after, before);
1691  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1692  }
1693 
1694  /*
1695  * In \gset mode, we force the fetch count to be 2, so that we will throw
1696  * the appropriate error if the query returns more than one row.
1697  */
1698  if (pset.gset_prefix)
1699  fetch_count = 2;
1700  else
1701  fetch_count = pset.fetch_count;
1702 
1703  snprintf(fetch_cmd, sizeof(fetch_cmd),
1704  "FETCH FORWARD %d FROM _psql_cursor",
1705  fetch_count);
1706 
1707  /* prepare to write output to \g argument, if any */
1708  if (pset.gfname)
1709  {
1710  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
1711  {
1712  OK = false;
1713  goto cleanup;
1714  }
1715  if (is_pipe)
1717  }
1718  else
1719  {
1720  fout = pset.queryFout;
1721  is_pipe = false; /* doesn't matter */
1722  }
1723 
1724  /* clear any pre-existing error indication on the output stream */
1725  clearerr(fout);
1726 
1727  for (;;)
1728  {
1729  if (timing)
1731 
1732  /* get fetch_count tuples at a time */
1733  result = PQexec(pset.db, fetch_cmd);
1734 
1735  if (timing)
1736  {
1737  INSTR_TIME_SET_CURRENT(after);
1738  INSTR_TIME_SUBTRACT(after, before);
1739  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1740  }
1741 
1742  if (PQresultStatus(result) != PGRES_TUPLES_OK)
1743  {
1744  /* shut down pager before printing error message */
1745  if (is_pager)
1746  {
1747  ClosePager(fout);
1748  is_pager = false;
1749  }
1750 
1751  OK = AcceptResult(result, true);
1752  Assert(!OK);
1753  SetResultVariables(result, OK);
1754  ClearOrSaveResult(result);
1755  break;
1756  }
1757 
1758  if (pset.gset_prefix)
1759  {
1760  /* StoreQueryTuple will complain if not exactly one row */
1761  OK = StoreQueryTuple(result);
1762  ClearOrSaveResult(result);
1763  break;
1764  }
1765 
1766  /*
1767  * Note we do not deal with \gdesc, \gexec or \crosstabview modes here
1768  */
1769 
1770  ntuples = PQntuples(result);
1771  total_tuples += ntuples;
1772 
1773  if (ntuples < fetch_count)
1774  {
1775  /* this is the last result set, so allow footer decoration */
1776  my_popt.topt.stop_table = true;
1777  }
1778  else if (fout == stdout && !is_pager)
1779  {
1780  /*
1781  * If query requires multiple result sets, hack to ensure that
1782  * only one pager instance is used for the whole mess
1783  */
1784  fout = PageOutput(INT_MAX, &(my_popt.topt));
1785  is_pager = true;
1786  }
1787 
1788  printQuery(result, &my_popt, fout, is_pager, pset.logfile);
1789 
1790  ClearOrSaveResult(result);
1791 
1792  /* after the first result set, disallow header decoration */
1793  my_popt.topt.start_table = false;
1794  my_popt.topt.prior_records += ntuples;
1795 
1796  /*
1797  * Make sure to flush the output stream, so intermediate results are
1798  * visible to the client immediately. We check the results because if
1799  * the pager dies/exits/etc, there's no sense throwing more data at
1800  * it.
1801  */
1802  flush_error = fflush(fout);
1803 
1804  /*
1805  * Check if we are at the end, if a cancel was pressed, or if there
1806  * were any errors either trying to flush out the results, or more
1807  * generally on the output stream at all. If we hit any errors
1808  * writing things to the stream, we presume $PAGER has disappeared and
1809  * stop bothering to pull down more data.
1810  */
1811  if (ntuples < fetch_count || cancel_pressed || flush_error ||
1812  ferror(fout))
1813  break;
1814  }
1815 
1816  if (pset.gfname)
1817  {
1818  /* close \g argument file/pipe */
1819  if (is_pipe)
1820  {
1821  pclose(fout);
1823  }
1824  else
1825  fclose(fout);
1826  }
1827  else if (is_pager)
1828  {
1829  /* close transient pager */
1830  ClosePager(fout);
1831  }
1832 
1833  if (OK)
1834  {
1835  /*
1836  * We don't have a PGresult here, and even if we did it wouldn't have
1837  * the right row count, so fake SetResultVariables(). In error cases,
1838  * we already set the result variables above.
1839  */
1840  char buf[32];
1841 
1842  SetVariable(pset.vars, "ERROR", "false");
1843  SetVariable(pset.vars, "SQLSTATE", "00000");
1844  snprintf(buf, sizeof(buf), INT64_FORMAT, total_tuples);
1845  SetVariable(pset.vars, "ROW_COUNT", buf);
1846  }
1847 
1848 cleanup:
1849  if (timing)
1851 
1852  /*
1853  * We try to close the cursor on either success or failure, but on failure
1854  * ignore the result (it's probably just a bleat about being in an aborted
1855  * transaction)
1856  */
1857  result = PQexec(pset.db, "CLOSE _psql_cursor");
1858  if (OK)
1859  {
1860  OK = AcceptResult(result, true) &&
1861  (PQresultStatus(result) == PGRES_COMMAND_OK);
1862  ClearOrSaveResult(result);
1863  }
1864  else
1865  PQclear(result);
1866 
1867  if (started_txn)
1868  {
1869  result = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK");
1870  OK &= AcceptResult(result, true) &&
1871  (PQresultStatus(result) == PGRES_COMMAND_OK);
1872  ClearOrSaveResult(result);
1873  }
1874 
1875  if (timing)
1876  {
1877  INSTR_TIME_SET_CURRENT(after);
1878  INSTR_TIME_SUBTRACT(after, before);
1879  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1880  }
1881 
1882  return OK;
1883 }
1884 
1885 
1886 /*
1887  * Advance the given char pointer over white space and SQL comments.
1888  */
1889 static const char *
1890 skip_white_space(const char *query)
1891 {
1892  int cnestlevel = 0; /* slash-star comment nest level */
1893 
1894  while (*query)
1895  {
1896  int mblen = PQmblenBounded(query, pset.encoding);
1897 
1898  /*
1899  * Note: we assume the encoding is a superset of ASCII, so that for
1900  * example "query[0] == '/'" is meaningful. However, we do NOT assume
1901  * that the second and subsequent bytes of a multibyte character
1902  * couldn't look like ASCII characters; so it is critical to advance
1903  * by mblen, not 1, whenever we haven't exactly identified the
1904  * character we are skipping over.
1905  */
1906  if (isspace((unsigned char) *query))
1907  query += mblen;
1908  else if (query[0] == '/' && query[1] == '*')
1909  {
1910  cnestlevel++;
1911  query += 2;
1912  }
1913  else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
1914  {
1915  cnestlevel--;
1916  query += 2;
1917  }
1918  else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
1919  {
1920  query += 2;
1921 
1922  /*
1923  * We have to skip to end of line since any slash-star inside the
1924  * -- comment does NOT start a slash-star comment.
1925  */
1926  while (*query)
1927  {
1928  if (*query == '\n')
1929  {
1930  query++;
1931  break;
1932  }
1933  query += PQmblenBounded(query, pset.encoding);
1934  }
1935  }
1936  else if (cnestlevel > 0)
1937  query += mblen;
1938  else
1939  break; /* found first token */
1940  }
1941 
1942  return query;
1943 }
1944 
1945 
1946 /*
1947  * Check whether a command is one of those for which we should NOT start
1948  * a new transaction block (ie, send a preceding BEGIN).
1949  *
1950  * These include the transaction control statements themselves, plus
1951  * certain statements that the backend disallows inside transaction blocks.
1952  */
1953 static bool
1954 command_no_begin(const char *query)
1955 {
1956  int wordlen;
1957 
1958  /*
1959  * First we must advance over any whitespace and comments.
1960  */
1961  query = skip_white_space(query);
1962 
1963  /*
1964  * Check word length (since "beginx" is not "begin").
1965  */
1966  wordlen = 0;
1967  while (isalpha((unsigned char) query[wordlen]))
1968  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
1969 
1970  /*
1971  * Transaction control commands. These should include every keyword that
1972  * gives rise to a TransactionStmt in the backend grammar, except for the
1973  * savepoint-related commands.
1974  *
1975  * (We assume that START must be START TRANSACTION, since there is
1976  * presently no other "START foo" command.)
1977  */
1978  if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
1979  return true;
1980  if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
1981  return true;
1982  if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
1983  return true;
1984  if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
1985  return true;
1986  if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
1987  return true;
1988  if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
1989  return true;
1990  if (wordlen == 7 && pg_strncasecmp(query, "prepare", 7) == 0)
1991  {
1992  /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
1993  query += wordlen;
1994 
1995  query = skip_white_space(query);
1996 
1997  wordlen = 0;
1998  while (isalpha((unsigned char) query[wordlen]))
1999  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2000 
2001  if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0)
2002  return true;
2003  return false;
2004  }
2005 
2006  /*
2007  * Commands not allowed within transactions. The statements checked for
2008  * here should be exactly those that call PreventInTransactionBlock() in
2009  * the backend.
2010  */
2011  if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
2012  return true;
2013  if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
2014  {
2015  /* CLUSTER with any arguments is allowed in transactions */
2016  query += wordlen;
2017 
2018  query = skip_white_space(query);
2019 
2020  if (isalpha((unsigned char) query[0]))
2021  return false; /* has additional words */
2022  return true; /* it's CLUSTER without arguments */
2023  }
2024 
2025  if (wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0)
2026  {
2027  query += wordlen;
2028 
2029  query = skip_white_space(query);
2030 
2031  wordlen = 0;
2032  while (isalpha((unsigned char) query[wordlen]))
2033  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2034 
2035  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
2036  return true;
2037  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
2038  return true;
2039 
2040  /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
2041  if (wordlen == 6 && pg_strncasecmp(query, "unique", 6) == 0)
2042  {
2043  query += wordlen;
2044 
2045  query = skip_white_space(query);
2046 
2047  wordlen = 0;
2048  while (isalpha((unsigned char) query[wordlen]))
2049  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2050  }
2051 
2052  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
2053  {
2054  query += wordlen;
2055 
2056  query = skip_white_space(query);
2057 
2058  wordlen = 0;
2059  while (isalpha((unsigned char) query[wordlen]))
2060  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2061 
2062  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2063  return true;
2064  }
2065 
2066  return false;
2067  }
2068 
2069  if (wordlen == 5 && pg_strncasecmp(query, "alter", 5) == 0)
2070  {
2071  query += wordlen;
2072 
2073  query = skip_white_space(query);
2074 
2075  wordlen = 0;
2076  while (isalpha((unsigned char) query[wordlen]))
2077  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2078 
2079  /* ALTER SYSTEM isn't allowed in xacts */
2080  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2081  return true;
2082 
2083  return false;
2084  }
2085 
2086  /*
2087  * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
2088  * aren't really valid commands so we don't care much. The other four
2089  * possible matches are correct.
2090  */
2091  if ((wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
2092  (wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
2093  {
2094  query += wordlen;
2095 
2096  query = skip_white_space(query);
2097 
2098  wordlen = 0;
2099  while (isalpha((unsigned char) query[wordlen]))
2100  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2101 
2102  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
2103  return true;
2104  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2105  return true;
2106  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
2107  return true;
2108  if (wordlen == 5 && (pg_strncasecmp(query, "index", 5) == 0 ||
2109  pg_strncasecmp(query, "table", 5) == 0))
2110  {
2111  query += wordlen;
2112  query = skip_white_space(query);
2113  wordlen = 0;
2114  while (isalpha((unsigned char) query[wordlen]))
2115  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2116 
2117  /*
2118  * REINDEX [ TABLE | INDEX ] CONCURRENTLY are not allowed in
2119  * xacts.
2120  */
2121  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2122  return true;
2123  }
2124 
2125  /* DROP INDEX CONCURRENTLY isn't allowed in xacts */
2126  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
2127  {
2128  query += wordlen;
2129 
2130  query = skip_white_space(query);
2131 
2132  wordlen = 0;
2133  while (isalpha((unsigned char) query[wordlen]))
2134  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2135 
2136  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2137  return true;
2138 
2139  return false;
2140  }
2141 
2142  return false;
2143  }
2144 
2145  /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */
2146  if (wordlen == 7 && pg_strncasecmp(query, "discard", 7) == 0)
2147  {
2148  query += wordlen;
2149 
2150  query = skip_white_space(query);
2151 
2152  wordlen = 0;
2153  while (isalpha((unsigned char) query[wordlen]))
2154  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2155 
2156  if (wordlen == 3 && pg_strncasecmp(query, "all", 3) == 0)
2157  return true;
2158  return false;
2159  }
2160 
2161  return false;
2162 }
2163 
2164 
2165 /*
2166  * Check whether the specified command is a SELECT (or VALUES).
2167  */
2168 static bool
2169 is_select_command(const char *query)
2170 {
2171  int wordlen;
2172 
2173  /*
2174  * First advance over any whitespace, comments and left parentheses.
2175  */
2176  for (;;)
2177  {
2178  query = skip_white_space(query);
2179  if (query[0] == '(')
2180  query++;
2181  else
2182  break;
2183  }
2184 
2185  /*
2186  * Check word length (since "selectx" is not "select").
2187  */
2188  wordlen = 0;
2189  while (isalpha((unsigned char) query[wordlen]))
2190  wordlen += PQmblenBounded(&query[wordlen], pset.encoding);
2191 
2192  if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
2193  return true;
2194 
2195  if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
2196  return true;
2197 
2198  return false;
2199 }
2200 
2201 
2202 /*
2203  * Test if the current user is a database superuser.
2204  */
2205 bool
2207 {
2208  const char *val;
2209 
2210  if (!pset.db)
2211  return false;
2212 
2213  val = PQparameterStatus(pset.db, "is_superuser");
2214 
2215  if (val && strcmp(val, "on") == 0)
2216  return true;
2217 
2218  return false;
2219 }
2220 
2221 
2222 /*
2223  * Test if the current session uses standard string literals.
2224  */
2225 bool
2227 {
2228  const char *val;
2229 
2230  if (!pset.db)
2231  return false;
2232 
2233  val = PQparameterStatus(pset.db, "standard_conforming_strings");
2234 
2235  if (val && strcmp(val, "on") == 0)
2236  return true;
2237 
2238  return false;
2239 }
2240 
2241 
2242 /*
2243  * Return the session user of the current connection.
2244  */
2245 const char *
2247 {
2248  const char *val;
2249 
2250  if (!pset.db)
2251  return NULL;
2252 
2253  val = PQparameterStatus(pset.db, "session_authorization");
2254  if (val)
2255  return val;
2256  else
2257  return PQuser(pset.db);
2258 }
2259 
2260 
2261 /* expand_tilde
2262  *
2263  * substitute '~' with HOME or '~username' with username's home dir
2264  *
2265  */
2266 void
2268 {
2269  if (!filename || !(*filename))
2270  return;
2271 
2272  /*
2273  * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2274  * for short versions of long file names, though the tilde is usually
2275  * toward the end, not at the beginning.
2276  */
2277 #ifndef WIN32
2278 
2279  /* try tilde expansion */
2280  if (**filename == '~')
2281  {
2282  char *fn;
2283  char oldp,
2284  *p;
2285  struct passwd *pw;
2286  char home[MAXPGPATH];
2287 
2288  fn = *filename;
2289  *home = '\0';
2290 
2291  p = fn + 1;
2292  while (*p != '/' && *p != '\0')
2293  p++;
2294 
2295  oldp = *p;
2296  *p = '\0';
2297 
2298  if (*(fn + 1) == '\0')
2299  get_home_path(home); /* ~ or ~/ only */
2300  else if ((pw = getpwnam(fn + 1)) != NULL)
2301  strlcpy(home, pw->pw_dir, sizeof(home)); /* ~user */
2302 
2303  *p = oldp;
2304  if (strlen(home) != 0)
2305  {
2306  char *newfn;
2307 
2308  newfn = psprintf("%s%s", home, p);
2309  free(fn);
2310  *filename = newfn;
2311  }
2312  }
2313 #endif
2314 }
2315 
2316 /*
2317  * Checks if connection string starts with either of the valid URI prefix
2318  * designators.
2319  *
2320  * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
2321  *
2322  * XXX This is a duplicate of the eponymous libpq function.
2323  */
2324 static int
2326 {
2327  /* The connection URI must start with either of the following designators: */
2328  static const char uri_designator[] = "postgresql://";
2329  static const char short_uri_designator[] = "postgres://";
2330 
2331  if (strncmp(connstr, uri_designator,
2332  sizeof(uri_designator) - 1) == 0)
2333  return sizeof(uri_designator) - 1;
2334 
2335  if (strncmp(connstr, short_uri_designator,
2336  sizeof(short_uri_designator) - 1) == 0)
2337  return sizeof(short_uri_designator) - 1;
2338 
2339  return 0;
2340 }
2341 
2342 /*
2343  * Recognized connection string either starts with a valid URI prefix or
2344  * contains a "=" in it.
2345  *
2346  * Must be consistent with parse_connection_string: anything for which this
2347  * returns true should at least look like it's parseable by that routine.
2348  *
2349  * XXX This is a duplicate of the eponymous libpq function.
2350  */
2351 bool
2353 {
2354  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
2355 }
const char *const days[]
Definition: datetime.c:83
static void setup_cancel_handler(void)
Definition: parallel.c:610
void expand_tilde(char **filename)
Definition: common.c:2267
void psql_setup_cancel_handler(void)
Definition: common.c:269
static bool CheckConnection(void)
Definition: common.c:298
static void PrintQueryStatus(PGresult *result, FILE *printQueryFout)
Definition: common.c:961
static int uri_prefix_length(const char *connstr)
Definition: common.c:2325
static bool DescribeQuery(const char *query, double *elapsed_msec)
Definition: common.c:1311
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1631
static void ClearOrSaveAllResults(void)
Definition: common.c:482
static bool ExecQueryTuples(const PGresult *result)
Definition: common.c:783
static void PrintNotifications(void)
Definition: common.c:640
static bool is_select_command(const char *query)
Definition: common.c:2169
char * psql_get_variable(const char *varname, PsqlScanQuoteType quote, void *passthrough)
Definition: common.c:132
const char * session_username(void)
Definition: common.c:2246
static bool PrintQueryResult(PGresult *result, bool last, bool is_watch, const printQueryOpt *opt, FILE *printQueryFout)
Definition: common.c:994
static void SetResultVariables(PGresult *result, bool success)
Definition: common.c:416
PGresult * PSQLexec(const char *query)
Definition: common.c:555
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:250
static void ClearOrSaveResult(PGresult *result)
Definition: common.c:458
static void psql_cancel_callback(void)
Definition: common.c:253
static bool AcceptResult(const PGresult *result, bool show_error)
Definition: common.c:359
void NoticeProcessor(void *arg, const char *message)
Definition: common.c:223
volatile bool sigint_interrupt_enabled
Definition: common.c:248
static bool StoreQueryTuple(const PGresult *result)
Definition: common.c:719
bool standard_strings(void)
Definition: common.c:2226
static bool PrintQueryTuples(const PGresult *result, const printQueryOpt *opt, FILE *printQueryFout)
Definition: common.c:667
static const char * skip_white_space(const char *query)
Definition: common.c:1890
static bool ConnectionUp(void)
Definition: common.c:280
static int ExecQueryAndProcessResults(const char *query, double *elapsed_msec, bool *svpt_gone_p, bool is_watch, const printQueryOpt *opt, FILE *printQueryFout)
Definition: common.c:1439
int PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout)
Definition: common.c:610
static bool HandleCopyResult(PGresult **resultp)
Definition: common.c:863
bool is_superuser(void)
Definition: common.c:2206
bool setQFout(const char *fname)
Definition: common.c:88
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
Definition: common.c:53
bool recognized_connection_string(const char *connstr)
Definition: common.c:2352
static void PrintTiming(double elapsed_msec)
Definition: common.c:496
bool SendQuery(const char *query)
Definition: common.c:1076
static bool command_no_begin(const char *query)
Definition: common.c:1954
bool handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res)
Definition: copy.c:435
bool handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
Definition: copy.c:512
static void cleanup(void)
Definition: bootstrap.c:696
#define gettext_noop(x)
Definition: c.h:1205
#define INT64_FORMAT
Definition: c.h:494
#define lengthof(array)
Definition: c.h:745
void ResetCancelConn(void)
Definition: cancel.c:107
void SetCancelConn(PGconn *conn)
Definition: cancel.c:77
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
Definition: command.c:4759
void UnsyncVariables(void)
Definition: command.c:3761
void SyncVariables(void)
Definition: command.c:3720
void connection_warnings(bool in_startup)
Definition: command.c:3595
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:140
bool PrintResultInCrosstab(const PGresult *res)
Definition: crosstabview.c:103
#define _(x)
Definition: elog.c:89
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
const char * name
Definition: encode.c:561
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6800
void PQreset(PGconn *conn)
Definition: fe-connect.c:4212
static const char short_uri_designator[]
Definition: fe-connect.c:372
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6790
static const char uri_designator[]
Definition: fe-connect.c:371
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6835
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6782
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6912
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4198
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6689
int PQbinaryTuples(const PGresult *res)
Definition: fe-exec.c:3431
void PQfreemem(void *ptr)
Definition: fe-exec.c:3966
PGnotify * PQnotifies(PGconn *conn)
Definition: fe-exec.c:2639
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
Definition: fe-exec.c:2358
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3653
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:4247
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3345
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
Definition: fe-exec.c:2509
char * PQcmdTuples(PGresult *res)
Definition: fe-exec.c:3756
char * PQresultErrorMessage(const PGresult *res)
Definition: fe-exec.c:3361
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3415
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3501
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:4241
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2314
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:2024
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3810
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3686
int PQfmod(const PGresult *res, int field_num)
Definition: fe-exec.c:3675
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3835
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1421
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3400
Oid PQoidValue(const PGresult *res)
Definition: fe-exec.c:3727
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3423
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:2102
int PQmblenBounded(const char *s, int encoding)
Definition: fe-misc.c:1195
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
void restore_sigpipe_trap(void)
Definition: print.c:3018
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3490
void ClosePager(FILE *pagerpipe)
Definition: print.c:3096
void disable_sigpipe_trap(void)
Definition: print.c:2995
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:3045
void html_escaped_print(const char *in, FILE *fout)
Definition: print.c:1908
void set_sigpipe_trap_state(bool ignore)
Definition: print.c:3031
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
@ PRINT_HTML
Definition: print.h:34
#define free(a)
Definition: header.h:65
static struct @151 value
long val
Definition: informix.c:664
static bool success
Definition: initdb.c:169
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
struct timeval instr_time
Definition: instr_time.h:150
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:202
int i
Definition: isn.c:73
@ CONNECTION_BAD
Definition: libpq-fe.h:61
ExecStatusType
Definition: libpq-fe.h:95
@ PGRES_COPY_IN
Definition: libpq-fe.h:104
@ PGRES_COPY_BOTH
Definition: libpq-fe.h:109
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:97
@ PGRES_FATAL_ERROR
Definition: libpq-fe.h:108
@ PGRES_COPY_OUT
Definition: libpq-fe.h:103
@ PGRES_EMPTY_QUERY
Definition: libpq-fe.h:96
@ PGRES_BAD_RESPONSE
Definition: libpq-fe.h:105
@ PGRES_NONFATAL_ERROR
Definition: libpq-fe.h:107
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:100
PGTransactionStatusType
Definition: libpq-fe.h:117
@ PQTRANS_INTRANS
Definition: libpq-fe.h:120
@ PQTRANS_IDLE
Definition: libpq-fe.h:118
@ PQTRANS_ACTIVE
Definition: libpq-fe.h:119
@ PQTRANS_UNKNOWN
Definition: libpq-fe.h:122
@ PQTRANS_INERROR
Definition: libpq-fe.h:121
static void const char fflush(stdout)
Assert(fmt[strlen(fmt) - 1] !='\n')
exit(1)
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_info(...)
Definition: logging.h:124
void * arg
#define MAXPGPATH
static char * connstr
Definition: pg_dumpall.c:63
static char * filename
Definition: pg_dumpall.c:94
static char * buf
Definition: pg_test_fsync.c:67
#define pg_log_warning(...)
Definition: pgfnames.c:24
bool get_home_path(char *ret_path)
Definition: path.c:928
#define snprintf
Definition: port.h:225
#define fprintf
Definition: port.h:229
#define printf(...)
Definition: port.h:231
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:64
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:65
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
char * c
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
PsqlScanQuoteType
Definition: psqlscan.h:53
@ PQUOTE_SQL_LITERAL
Definition: psqlscan.h:55
@ PQUOTE_PLAIN
Definition: psqlscan.h:54
@ PQUOTE_SHELL_ARG
Definition: psqlscan.h:57
@ PQUOTE_SQL_IDENT
Definition: psqlscan.h:56
static int before(chr x, chr y)
Definition: regc_locale.c:492
@ PSQL_ERROR_ROLLBACK_ON
Definition: settings.h:54
@ PSQL_ERROR_ROLLBACK_OFF
Definition: settings.h:52
@ PSQL_ECHO_ALL
Definition: settings.h:40
@ PSQL_ECHO_ERRORS
Definition: settings.h:39
@ PSQL_ECHO_QUERIES
Definition: settings.h:38
@ PSQL_ECHO_HIDDEN_NOEXEC
Definition: settings.h:47
@ PSQL_ECHO_HIDDEN_OFF
Definition: settings.h:45
PsqlSettings pset
Definition: startup.c:32
#define EXIT_BADCONN
Definition: settings.h:166
static void error(void)
Definition: sql-dyntest.c:147
bool appendShellStringNoError(PQExpBuffer buf, const char *str)
Definition: string_utils.c:441
printQueryOpt popt
Definition: settings.h:91
char * gset_prefix
Definition: settings.h:96
PSQL_ERROR_ROLLBACK on_error_rollback
Definition: settings.h:144
VariableSpace vars
Definition: settings.h:118
int encoding
Definition: settings.h:83
FILE * logfile
Definition: settings.h:116
bool on_error_stop
Definition: settings.h:133
PGconn * dead_conn
Definition: settings.h:125
bool autocommit
Definition: settings.h:132
char * ctv_args[4]
Definition: settings.h:100
PGresult * last_error_result
Definition: settings.h:89
bool show_all_results
Definition: settings.h:151
FILE * copyStream
Definition: settings.h:87
PGconn * db
Definition: settings.h:82
FILE * queryFout
Definition: settings.h:84
bool queryFoutPipe
Definition: settings.h:85
PSQL_ECHO echo
Definition: settings.h:142
bool singlestep
Definition: settings.h:136
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:143
printQueryOpt * gsavepopt
Definition: settings.h:94
char * gfname
Definition: settings.h:93
int fetch_count
Definition: settings.h:139
bool cur_cmd_interactive
Definition: settings.h:107
bool gexec_flag
Definition: settings.h:98
bool crosstab_flag
Definition: settings.h:99
FILE * cur_cmd_source
Definition: settings.h:105
bool gdesc_flag
Definition: settings.h:97
int be_pid
Definition: libpq-fe.h:190
char * relname
Definition: libpq-fe.h:189
char * extra
Definition: libpq-fe.h:191
printTableOpt topt
Definition: print.h:169
bool start_table
Definition: print.h:111
unsigned long prior_records
Definition: print.h:114
enum printFormat format
Definition: print.h:101
int encoding
Definition: print.h:122
bool stop_table
Definition: print.h:112
static void * fn(void *arg)
bool VariableHasHook(VariableSpace space, const char *name)
Definition: variables.c:367
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211
const char * GetVariable(VariableSpace space, const char *name)
Definition: variables.c:71