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-2021, 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 COMMIT AND CHAIN, RELEASE or ROLLBACK, our
1354  * savepoint is gone. If they issued a SAVEPOINT, releasing
1355  * ours would remove theirs.
1356  */
1357  if (results &&
1358  (strcmp(PQcmdStatus(results), "COMMIT") == 0 ||
1359  strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
1360  strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
1361  strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
1362  svptcmd = NULL;
1363  else
1364  svptcmd = "RELEASE pg_psql_temporary_savepoint";
1365  break;
1366 
1367  case PQTRANS_ACTIVE:
1368  case PQTRANS_UNKNOWN:
1369  default:
1370  OK = false;
1371  /* PQTRANS_UNKNOWN is expected given a broken connection. */
1372  if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp())
1373  pg_log_error("unexpected transaction status (%d)",
1374  transaction_status);
1375  break;
1376  }
1377 
1378  if (svptcmd)
1379  {
1380  PGresult *svptres;
1381 
1382  svptres = PQexec(pset.db, svptcmd);
1383  if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
1384  {
1386  ClearOrSaveResult(svptres);
1387  OK = false;
1388 
1389  PQclear(results);
1390  ResetCancelConn();
1391  goto sendquery_cleanup;
1392  }
1393  PQclear(svptres);
1394  }
1395  }
1396 
1397  ClearOrSaveResult(results);
1398 
1399  /* Possible microtiming output */
1400  if (pset.timing)
1401  PrintTiming(elapsed_msec);
1402 
1403  /* check for events that may occur during query execution */
1404 
1405  if (pset.encoding != PQclientEncoding(pset.db) &&
1406  PQclientEncoding(pset.db) >= 0)
1407  {
1408  /* track effects of SET CLIENT_ENCODING */
1411  SetVariable(pset.vars, "ENCODING",
1413  }
1414 
1416 
1417  /* perform cleanup that should occur after any attempted query */
1418 
1419 sendquery_cleanup:
1420 
1421  /* reset \g's output-to-filename trigger */
1422  if (pset.gfname)
1423  {
1424  free(pset.gfname);
1425  pset.gfname = NULL;
1426  }
1427 
1428  /* restore print settings if \g changed them */
1429  if (pset.gsavepopt)
1430  {
1432  pset.gsavepopt = NULL;
1433  }
1434 
1435  /* reset \gset trigger */
1436  if (pset.gset_prefix)
1437  {
1439  pset.gset_prefix = NULL;
1440  }
1441 
1442  /* reset \gdesc trigger */
1443  pset.gdesc_flag = false;
1444 
1445  /* reset \gexec trigger */
1446  pset.gexec_flag = false;
1447 
1448  /* reset \crosstabview trigger */
1449  pset.crosstab_flag = false;
1450  for (i = 0; i < lengthof(pset.ctv_args); i++)
1451  {
1452  pg_free(pset.ctv_args[i]);
1453  pset.ctv_args[i] = NULL;
1454  }
1455 
1456  return OK;
1457 }
1458 
1459 
1460 /*
1461  * DescribeQuery: describe the result columns of a query, without executing it
1462  *
1463  * Returns true if the operation executed successfully, false otherwise.
1464  *
1465  * If pset.timing is on, total query time (exclusive of result-printing) is
1466  * stored into *elapsed_msec.
1467  */
1468 static bool
1469 DescribeQuery(const char *query, double *elapsed_msec)
1470 {
1471  PGresult *results;
1472  bool OK;
1474  after;
1475 
1476  *elapsed_msec = 0;
1477 
1478  if (pset.timing)
1479  INSTR_TIME_SET_CURRENT(before);
1480 
1481  /*
1482  * To parse the query but not execute it, we prepare it, using the unnamed
1483  * prepared statement. This is invisible to psql users, since there's no
1484  * way to access the unnamed prepared statement from psql user space. The
1485  * next Parse or Query protocol message would overwrite the statement
1486  * anyway. (So there's no great need to clear it when done, which is a
1487  * good thing because libpq provides no easy way to do that.)
1488  */
1489  results = PQprepare(pset.db, "", query, 0, NULL);
1490  if (PQresultStatus(results) != PGRES_COMMAND_OK)
1491  {
1493  SetResultVariables(results, false);
1494  ClearOrSaveResult(results);
1495  return false;
1496  }
1497  PQclear(results);
1498 
1499  results = PQdescribePrepared(pset.db, "");
1500  OK = AcceptResult(results) &&
1501  (PQresultStatus(results) == PGRES_COMMAND_OK);
1502  if (OK && results)
1503  {
1504  if (PQnfields(results) > 0)
1505  {
1507  int i;
1508 
1509  initPQExpBuffer(&buf);
1510 
1511  printfPQExpBuffer(&buf,
1512  "SELECT name AS \"%s\", pg_catalog.format_type(tp, tpm) AS \"%s\"\n"
1513  "FROM (VALUES ",
1514  gettext_noop("Column"),
1515  gettext_noop("Type"));
1516 
1517  for (i = 0; i < PQnfields(results); i++)
1518  {
1519  const char *name;
1520  char *escname;
1521 
1522  if (i > 0)
1523  appendPQExpBufferStr(&buf, ",");
1524 
1525  name = PQfname(results, i);
1526  escname = PQescapeLiteral(pset.db, name, strlen(name));
1527 
1528  if (escname == NULL)
1529  {
1531  PQclear(results);
1532  termPQExpBuffer(&buf);
1533  return false;
1534  }
1535 
1536  appendPQExpBuffer(&buf, "(%s, '%u'::pg_catalog.oid, %d)",
1537  escname,
1538  PQftype(results, i),
1539  PQfmod(results, i));
1540 
1541  PQfreemem(escname);
1542  }
1543 
1544  appendPQExpBufferStr(&buf, ") s(name, tp, tpm)");
1545  PQclear(results);
1546 
1547  results = PQexec(pset.db, buf.data);
1548  OK = AcceptResult(results);
1549 
1550  if (pset.timing)
1551  {
1552  INSTR_TIME_SET_CURRENT(after);
1553  INSTR_TIME_SUBTRACT(after, before);
1554  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1555  }
1556 
1557  if (OK && results)
1558  OK = PrintQueryResults(results);
1559 
1560  termPQExpBuffer(&buf);
1561  }
1562  else
1564  _("The command has no result, or the result has no columns.\n"));
1565  }
1566 
1567  SetResultVariables(results, OK);
1568  ClearOrSaveResult(results);
1569 
1570  return OK;
1571 }
1572 
1573 
1574 /*
1575  * ExecQueryUsingCursor: run a SELECT-like query using a cursor
1576  *
1577  * This feature allows result sets larger than RAM to be dealt with.
1578  *
1579  * Returns true if the query executed successfully, false otherwise.
1580  *
1581  * If pset.timing is on, total query time (exclusive of result-printing) is
1582  * stored into *elapsed_msec.
1583  */
1584 static bool
1585 ExecQueryUsingCursor(const char *query, double *elapsed_msec)
1586 {
1587  bool OK = true;
1588  PGresult *results;
1590  printQueryOpt my_popt = pset.popt;
1591  FILE *fout;
1592  bool is_pipe;
1593  bool is_pager = false;
1594  bool started_txn = false;
1595  int64 total_tuples = 0;
1596  int ntuples;
1597  int fetch_count;
1598  char fetch_cmd[64];
1600  after;
1601  int flush_error;
1602 
1603  *elapsed_msec = 0;
1604 
1605  /* initialize print options for partial table output */
1606  my_popt.topt.start_table = true;
1607  my_popt.topt.stop_table = false;
1608  my_popt.topt.prior_records = 0;
1609 
1610  if (pset.timing)
1611  INSTR_TIME_SET_CURRENT(before);
1612 
1613  /* if we're not in a transaction, start one */
1615  {
1616  results = PQexec(pset.db, "BEGIN");
1617  OK = AcceptResult(results) &&
1618  (PQresultStatus(results) == PGRES_COMMAND_OK);
1619  ClearOrSaveResult(results);
1620  if (!OK)
1621  return false;
1622  started_txn = true;
1623  }
1624 
1625  /* Send DECLARE CURSOR */
1626  initPQExpBuffer(&buf);
1627  appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1628  query);
1629 
1630  results = PQexec(pset.db, buf.data);
1631  OK = AcceptResult(results) &&
1632  (PQresultStatus(results) == PGRES_COMMAND_OK);
1633  if (!OK)
1634  SetResultVariables(results, OK);
1635  ClearOrSaveResult(results);
1636  termPQExpBuffer(&buf);
1637  if (!OK)
1638  goto cleanup;
1639 
1640  if (pset.timing)
1641  {
1642  INSTR_TIME_SET_CURRENT(after);
1643  INSTR_TIME_SUBTRACT(after, before);
1644  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1645  }
1646 
1647  /*
1648  * In \gset mode, we force the fetch count to be 2, so that we will throw
1649  * the appropriate error if the query returns more than one row.
1650  */
1651  if (pset.gset_prefix)
1652  fetch_count = 2;
1653  else
1654  fetch_count = pset.fetch_count;
1655 
1656  snprintf(fetch_cmd, sizeof(fetch_cmd),
1657  "FETCH FORWARD %d FROM _psql_cursor",
1658  fetch_count);
1659 
1660  /* prepare to write output to \g argument, if any */
1661  if (pset.gfname)
1662  {
1663  if (!openQueryOutputFile(pset.gfname, &fout, &is_pipe))
1664  {
1665  OK = false;
1666  goto cleanup;
1667  }
1668  if (is_pipe)
1670  }
1671  else
1672  {
1673  fout = pset.queryFout;
1674  is_pipe = false; /* doesn't matter */
1675  }
1676 
1677  /* clear any pre-existing error indication on the output stream */
1678  clearerr(fout);
1679 
1680  for (;;)
1681  {
1682  if (pset.timing)
1683  INSTR_TIME_SET_CURRENT(before);
1684 
1685  /* get fetch_count tuples at a time */
1686  results = PQexec(pset.db, fetch_cmd);
1687 
1688  if (pset.timing)
1689  {
1690  INSTR_TIME_SET_CURRENT(after);
1691  INSTR_TIME_SUBTRACT(after, before);
1692  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1693  }
1694 
1695  if (PQresultStatus(results) != PGRES_TUPLES_OK)
1696  {
1697  /* shut down pager before printing error message */
1698  if (is_pager)
1699  {
1700  ClosePager(fout);
1701  is_pager = false;
1702  }
1703 
1704  OK = AcceptResult(results);
1705  Assert(!OK);
1706  SetResultVariables(results, OK);
1707  ClearOrSaveResult(results);
1708  break;
1709  }
1710 
1711  if (pset.gset_prefix)
1712  {
1713  /* StoreQueryTuple will complain if not exactly one row */
1714  OK = StoreQueryTuple(results);
1715  ClearOrSaveResult(results);
1716  break;
1717  }
1718 
1719  /*
1720  * Note we do not deal with \gdesc, \gexec or \crosstabview modes here
1721  */
1722 
1723  ntuples = PQntuples(results);
1724  total_tuples += ntuples;
1725 
1726  if (ntuples < fetch_count)
1727  {
1728  /* this is the last result set, so allow footer decoration */
1729  my_popt.topt.stop_table = true;
1730  }
1731  else if (fout == stdout && !is_pager)
1732  {
1733  /*
1734  * If query requires multiple result sets, hack to ensure that
1735  * only one pager instance is used for the whole mess
1736  */
1737  fout = PageOutput(INT_MAX, &(my_popt.topt));
1738  is_pager = true;
1739  }
1740 
1741  printQuery(results, &my_popt, fout, is_pager, pset.logfile);
1742 
1743  ClearOrSaveResult(results);
1744 
1745  /* after the first result set, disallow header decoration */
1746  my_popt.topt.start_table = false;
1747  my_popt.topt.prior_records += ntuples;
1748 
1749  /*
1750  * Make sure to flush the output stream, so intermediate results are
1751  * visible to the client immediately. We check the results because if
1752  * the pager dies/exits/etc, there's no sense throwing more data at
1753  * it.
1754  */
1755  flush_error = fflush(fout);
1756 
1757  /*
1758  * Check if we are at the end, if a cancel was pressed, or if there
1759  * were any errors either trying to flush out the results, or more
1760  * generally on the output stream at all. If we hit any errors
1761  * writing things to the stream, we presume $PAGER has disappeared and
1762  * stop bothering to pull down more data.
1763  */
1764  if (ntuples < fetch_count || cancel_pressed || flush_error ||
1765  ferror(fout))
1766  break;
1767  }
1768 
1769  if (pset.gfname)
1770  {
1771  /* close \g argument file/pipe */
1772  if (is_pipe)
1773  {
1774  pclose(fout);
1776  }
1777  else
1778  fclose(fout);
1779  }
1780  else if (is_pager)
1781  {
1782  /* close transient pager */
1783  ClosePager(fout);
1784  }
1785 
1786  if (OK)
1787  {
1788  /*
1789  * We don't have a PGresult here, and even if we did it wouldn't have
1790  * the right row count, so fake SetResultVariables(). In error cases,
1791  * we already set the result variables above.
1792  */
1793  char buf[32];
1794 
1795  SetVariable(pset.vars, "ERROR", "false");
1796  SetVariable(pset.vars, "SQLSTATE", "00000");
1797  snprintf(buf, sizeof(buf), INT64_FORMAT, total_tuples);
1798  SetVariable(pset.vars, "ROW_COUNT", buf);
1799  }
1800 
1801 cleanup:
1802  if (pset.timing)
1803  INSTR_TIME_SET_CURRENT(before);
1804 
1805  /*
1806  * We try to close the cursor on either success or failure, but on failure
1807  * ignore the result (it's probably just a bleat about being in an aborted
1808  * transaction)
1809  */
1810  results = PQexec(pset.db, "CLOSE _psql_cursor");
1811  if (OK)
1812  {
1813  OK = AcceptResult(results) &&
1814  (PQresultStatus(results) == PGRES_COMMAND_OK);
1815  ClearOrSaveResult(results);
1816  }
1817  else
1818  PQclear(results);
1819 
1820  if (started_txn)
1821  {
1822  results = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK");
1823  OK &= AcceptResult(results) &&
1824  (PQresultStatus(results) == PGRES_COMMAND_OK);
1825  ClearOrSaveResult(results);
1826  }
1827 
1828  if (pset.timing)
1829  {
1830  INSTR_TIME_SET_CURRENT(after);
1831  INSTR_TIME_SUBTRACT(after, before);
1832  *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1833  }
1834 
1835  return OK;
1836 }
1837 
1838 
1839 /*
1840  * Advance the given char pointer over white space and SQL comments.
1841  */
1842 static const char *
1843 skip_white_space(const char *query)
1844 {
1845  int cnestlevel = 0; /* slash-star comment nest level */
1846 
1847  while (*query)
1848  {
1849  int mblen = PQmblen(query, pset.encoding);
1850 
1851  /*
1852  * Note: we assume the encoding is a superset of ASCII, so that for
1853  * example "query[0] == '/'" is meaningful. However, we do NOT assume
1854  * that the second and subsequent bytes of a multibyte character
1855  * couldn't look like ASCII characters; so it is critical to advance
1856  * by mblen, not 1, whenever we haven't exactly identified the
1857  * character we are skipping over.
1858  */
1859  if (isspace((unsigned char) *query))
1860  query += mblen;
1861  else if (query[0] == '/' && query[1] == '*')
1862  {
1863  cnestlevel++;
1864  query += 2;
1865  }
1866  else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
1867  {
1868  cnestlevel--;
1869  query += 2;
1870  }
1871  else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
1872  {
1873  query += 2;
1874 
1875  /*
1876  * We have to skip to end of line since any slash-star inside the
1877  * -- comment does NOT start a slash-star comment.
1878  */
1879  while (*query)
1880  {
1881  if (*query == '\n')
1882  {
1883  query++;
1884  break;
1885  }
1886  query += PQmblen(query, pset.encoding);
1887  }
1888  }
1889  else if (cnestlevel > 0)
1890  query += mblen;
1891  else
1892  break; /* found first token */
1893  }
1894 
1895  return query;
1896 }
1897 
1898 
1899 /*
1900  * Check whether a command is one of those for which we should NOT start
1901  * a new transaction block (ie, send a preceding BEGIN).
1902  *
1903  * These include the transaction control statements themselves, plus
1904  * certain statements that the backend disallows inside transaction blocks.
1905  */
1906 static bool
1907 command_no_begin(const char *query)
1908 {
1909  int wordlen;
1910 
1911  /*
1912  * First we must advance over any whitespace and comments.
1913  */
1914  query = skip_white_space(query);
1915 
1916  /*
1917  * Check word length (since "beginx" is not "begin").
1918  */
1919  wordlen = 0;
1920  while (isalpha((unsigned char) query[wordlen]))
1921  wordlen += PQmblen(&query[wordlen], pset.encoding);
1922 
1923  /*
1924  * Transaction control commands. These should include every keyword that
1925  * gives rise to a TransactionStmt in the backend grammar, except for the
1926  * savepoint-related commands.
1927  *
1928  * (We assume that START must be START TRANSACTION, since there is
1929  * presently no other "START foo" command.)
1930  */
1931  if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
1932  return true;
1933  if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
1934  return true;
1935  if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
1936  return true;
1937  if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
1938  return true;
1939  if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
1940  return true;
1941  if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
1942  return true;
1943  if (wordlen == 7 && pg_strncasecmp(query, "prepare", 7) == 0)
1944  {
1945  /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
1946  query += wordlen;
1947 
1948  query = skip_white_space(query);
1949 
1950  wordlen = 0;
1951  while (isalpha((unsigned char) query[wordlen]))
1952  wordlen += PQmblen(&query[wordlen], pset.encoding);
1953 
1954  if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0)
1955  return true;
1956  return false;
1957  }
1958 
1959  /*
1960  * Commands not allowed within transactions. The statements checked for
1961  * here should be exactly those that call PreventInTransactionBlock() in
1962  * the backend.
1963  */
1964  if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
1965  return true;
1966  if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
1967  {
1968  /* CLUSTER with any arguments is allowed in transactions */
1969  query += wordlen;
1970 
1971  query = skip_white_space(query);
1972 
1973  if (isalpha((unsigned char) query[0]))
1974  return false; /* has additional words */
1975  return true; /* it's CLUSTER without arguments */
1976  }
1977 
1978  if (wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0)
1979  {
1980  query += wordlen;
1981 
1982  query = skip_white_space(query);
1983 
1984  wordlen = 0;
1985  while (isalpha((unsigned char) query[wordlen]))
1986  wordlen += PQmblen(&query[wordlen], pset.encoding);
1987 
1988  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
1989  return true;
1990  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
1991  return true;
1992 
1993  /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
1994  if (wordlen == 6 && pg_strncasecmp(query, "unique", 6) == 0)
1995  {
1996  query += wordlen;
1997 
1998  query = skip_white_space(query);
1999 
2000  wordlen = 0;
2001  while (isalpha((unsigned char) query[wordlen]))
2002  wordlen += PQmblen(&query[wordlen], pset.encoding);
2003  }
2004 
2005  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
2006  {
2007  query += wordlen;
2008 
2009  query = skip_white_space(query);
2010 
2011  wordlen = 0;
2012  while (isalpha((unsigned char) query[wordlen]))
2013  wordlen += PQmblen(&query[wordlen], pset.encoding);
2014 
2015  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2016  return true;
2017  }
2018 
2019  return false;
2020  }
2021 
2022  if (wordlen == 5 && pg_strncasecmp(query, "alter", 5) == 0)
2023  {
2024  query += wordlen;
2025 
2026  query = skip_white_space(query);
2027 
2028  wordlen = 0;
2029  while (isalpha((unsigned char) query[wordlen]))
2030  wordlen += PQmblen(&query[wordlen], pset.encoding);
2031 
2032  /* ALTER SYSTEM isn't allowed in xacts */
2033  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2034  return true;
2035 
2036  return false;
2037  }
2038 
2039  /*
2040  * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
2041  * aren't really valid commands so we don't care much. The other four
2042  * possible matches are correct.
2043  */
2044  if ((wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
2045  (wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
2046  {
2047  query += wordlen;
2048 
2049  query = skip_white_space(query);
2050 
2051  wordlen = 0;
2052  while (isalpha((unsigned char) query[wordlen]))
2053  wordlen += PQmblen(&query[wordlen], pset.encoding);
2054 
2055  if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
2056  return true;
2057  if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
2058  return true;
2059  if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
2060  return true;
2061  if (wordlen == 5 && (pg_strncasecmp(query, "index", 5) == 0 ||
2062  pg_strncasecmp(query, "table", 5) == 0))
2063  {
2064  query += wordlen;
2065  query = skip_white_space(query);
2066  wordlen = 0;
2067  while (isalpha((unsigned char) query[wordlen]))
2068  wordlen += PQmblen(&query[wordlen], pset.encoding);
2069 
2070  /*
2071  * REINDEX [ TABLE | INDEX ] CONCURRENTLY are not allowed in
2072  * xacts.
2073  */
2074  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2075  return true;
2076  }
2077 
2078  /* DROP INDEX CONCURRENTLY isn't allowed in xacts */
2079  if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
2080  {
2081  query += wordlen;
2082 
2083  query = skip_white_space(query);
2084 
2085  wordlen = 0;
2086  while (isalpha((unsigned char) query[wordlen]))
2087  wordlen += PQmblen(&query[wordlen], pset.encoding);
2088 
2089  if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
2090  return true;
2091 
2092  return false;
2093  }
2094 
2095  return false;
2096  }
2097 
2098  /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */
2099  if (wordlen == 7 && pg_strncasecmp(query, "discard", 7) == 0)
2100  {
2101  query += wordlen;
2102 
2103  query = skip_white_space(query);
2104 
2105  wordlen = 0;
2106  while (isalpha((unsigned char) query[wordlen]))
2107  wordlen += PQmblen(&query[wordlen], pset.encoding);
2108 
2109  if (wordlen == 3 && pg_strncasecmp(query, "all", 3) == 0)
2110  return true;
2111  return false;
2112  }
2113 
2114  return false;
2115 }
2116 
2117 
2118 /*
2119  * Check whether the specified command is a SELECT (or VALUES).
2120  */
2121 static bool
2122 is_select_command(const char *query)
2123 {
2124  int wordlen;
2125 
2126  /*
2127  * First advance over any whitespace, comments and left parentheses.
2128  */
2129  for (;;)
2130  {
2131  query = skip_white_space(query);
2132  if (query[0] == '(')
2133  query++;
2134  else
2135  break;
2136  }
2137 
2138  /*
2139  * Check word length (since "selectx" is not "select").
2140  */
2141  wordlen = 0;
2142  while (isalpha((unsigned char) query[wordlen]))
2143  wordlen += PQmblen(&query[wordlen], pset.encoding);
2144 
2145  if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
2146  return true;
2147 
2148  if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
2149  return true;
2150 
2151  return false;
2152 }
2153 
2154 
2155 /*
2156  * Test if the current user is a database superuser.
2157  */
2158 bool
2160 {
2161  const char *val;
2162 
2163  if (!pset.db)
2164  return false;
2165 
2166  val = PQparameterStatus(pset.db, "is_superuser");
2167 
2168  if (val && strcmp(val, "on") == 0)
2169  return true;
2170 
2171  return false;
2172 }
2173 
2174 
2175 /*
2176  * Test if the current session uses standard string literals.
2177  */
2178 bool
2180 {
2181  const char *val;
2182 
2183  if (!pset.db)
2184  return false;
2185 
2186  val = PQparameterStatus(pset.db, "standard_conforming_strings");
2187 
2188  if (val && strcmp(val, "on") == 0)
2189  return true;
2190 
2191  return false;
2192 }
2193 
2194 
2195 /*
2196  * Return the session user of the current connection.
2197  */
2198 const char *
2200 {
2201  const char *val;
2202 
2203  if (!pset.db)
2204  return NULL;
2205 
2206  val = PQparameterStatus(pset.db, "session_authorization");
2207  if (val)
2208  return val;
2209  else
2210  return PQuser(pset.db);
2211 }
2212 
2213 
2214 /* expand_tilde
2215  *
2216  * substitute '~' with HOME or '~username' with username's home dir
2217  *
2218  */
2219 void
2221 {
2222  if (!filename || !(*filename))
2223  return;
2224 
2225  /*
2226  * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2227  * for short versions of long file names, though the tilde is usually
2228  * toward the end, not at the beginning.
2229  */
2230 #ifndef WIN32
2231 
2232  /* try tilde expansion */
2233  if (**filename == '~')
2234  {
2235  char *fn;
2236  char oldp,
2237  *p;
2238  struct passwd *pw;
2239  char home[MAXPGPATH];
2240 
2241  fn = *filename;
2242  *home = '\0';
2243 
2244  p = fn + 1;
2245  while (*p != '/' && *p != '\0')
2246  p++;
2247 
2248  oldp = *p;
2249  *p = '\0';
2250 
2251  if (*(fn + 1) == '\0')
2252  get_home_path(home); /* ~ or ~/ only */
2253  else if ((pw = getpwnam(fn + 1)) != NULL)
2254  strlcpy(home, pw->pw_dir, sizeof(home)); /* ~user */
2255 
2256  *p = oldp;
2257  if (strlen(home) != 0)
2258  {
2259  char *newfn;
2260 
2261  newfn = psprintf("%s%s", home, p);
2262  free(fn);
2263  *filename = newfn;
2264  }
2265  }
2266 #endif
2267 }
2268 
2269 /*
2270  * Checks if connection string starts with either of the valid URI prefix
2271  * designators.
2272  *
2273  * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
2274  *
2275  * XXX This is a duplicate of the eponymous libpq function.
2276  */
2277 static int
2279 {
2280  /* The connection URI must start with either of the following designators: */
2281  static const char uri_designator[] = "postgresql://";
2282  static const char short_uri_designator[] = "postgres://";
2283 
2284  if (strncmp(connstr, uri_designator,
2285  sizeof(uri_designator) - 1) == 0)
2286  return sizeof(uri_designator) - 1;
2287 
2288  if (strncmp(connstr, short_uri_designator,
2289  sizeof(short_uri_designator) - 1) == 0)
2290  return sizeof(short_uri_designator) - 1;
2291 
2292  return 0;
2293 }
2294 
2295 /*
2296  * Recognized connection string either starts with a valid URI prefix or
2297  * contains a "=" in it.
2298  *
2299  * Must be consistent with parse_connection_string: anything for which this
2300  * returns true should at least look like it's parseable by that routine.
2301  *
2302  * XXX This is a duplicate of the eponymous libpq function.
2303  */
2304 bool
2306 {
2307  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
2308 }
static void PrintQueryStatus(PGresult *results)
Definition: common.c:1083
PSQL_ECHO echo
Definition: settings.h:142
bool singlestep
Definition: settings.h:136
char * gset_prefix
Definition: settings.h:96
char * extra
Definition: libpq-fe.h:180
static bool PrintQueryResults(PGresult *results)
Definition: common.c:1115
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3175
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
Definition: fe-exec.c:2186
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6735
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
Definition: fe-exec.c:2335
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:3660
static struct @142 value
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3561
static void error(void)
Definition: sql-dyntest.c:147
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6700
PGnotify * PQnotifies(PGconn *conn)
Definition: fe-exec.c:2466
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3253
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:3508
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:2305
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:202
Oid PQoidValue(const PGresult *res)
Definition: fe-exec.c:3479
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:1197
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:4229
static bool CheckConnection(void)
Definition: common.c:295
#define printf(...)
Definition: port.h:222
static bool ConnectionUp(void)
Definition: common.c:277
ExecStatusType
Definition: libpq-fe.h:83
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:734
int PQbinaryTuples(const PGresult *res)
Definition: fe-exec.c:3183
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
#define fprintf
Definition: port.h:220
unsigned long prior_records
Definition: print.h:114
FILE * copyStream
Definition: settings.h:87
PSQL_ERROR_ROLLBACK on_error_rollback
Definition: settings.h:144
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6804
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
FILE * cur_cmd_source
Definition: settings.h:105
void UnsyncVariables(void)
Definition: command.c:3701
static bool AcceptResult(const PGresult *result)
Definition: common.c:356
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6589
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:247
#define EXIT_BADCONN
Definition: settings.h:165
static void PrintNotifications(void)
Definition: common.c:685
static int uri_prefix_length(const char *connstr)
Definition: common.c:2278
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:3994
static int before(chr x, chr y)
Definition: regc_locale.c:492
bool cur_cmd_interactive
Definition: settings.h:107
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:143
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:2975
static bool is_select_command(const char *query)
Definition: common.c:2122
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:170
int be_pid
Definition: libpq-fe.h:179
void expand_tilde(char **filename)
Definition: common.c:2220
#define MAXPGPATH
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
Definition: command.c:4699
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3405
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:2199
int fetch_count
Definition: settings.h:139
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:178
void restore_sigpipe_trap(void)
Definition: print.c:2948
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec)
Definition: common.c:1585
PsqlScanQuoteType
Definition: psqlscan.h:52
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6690
const char * GetVariable(VariableSpace space, const char *name)
Definition: variables.c:71
static bool DescribeQuery(const char *query, double *elapsed_msec)
Definition: common.c:1469
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:3438
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:872
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1853
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:3988
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
bool stop_table
Definition: print.h:112
void PQclear(PGresult *res)
Definition: fe-exec.c:680
static void * fn(void *arg)
bool is_superuser(void)
Definition: common.c:2159
bool standard_strings(void)
Definition: common.c:2179
#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:105
char * title
Definition: print.h:171
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3152
#define Assert(condition)
Definition: c.h:804
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:3427
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:3420
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:483
const char * name
Definition: encode.c:515
static const char short_uri_designator[]
Definition: fe-connect.c:373
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:372
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:2142
void * arg
bool SendQuery(const char *query)
Definition: common.c:1190
void connection_warnings(bool in_startup)
Definition: command.c:3537
#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:3586
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6682
static bool command_no_begin(const char *query)
Definition: common.c:1907
static bool success
Definition: initdb.c:165
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1187
#define snprintf
Definition: port.h:216
#define _(x)
Definition: elog.c:89
void PQfreemem(void *ptr)
Definition: fe-exec.c:3715
long val
Definition: informix.c:664
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1927
static const char * skip_white_space(const char *query)
Definition: common.c:1843
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
#define pg_log_info(...)
Definition: logging.h:88
void PQreset(PGconn *conn)
Definition: fe-connect.c:4243
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