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