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