]> granicus.if.org Git - postgresql/blob - src/bin/psql/common.c
ed929372420fba4c9bf9077cec112f103b15971c
[postgresql] / src / bin / psql / common.c
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2010, PostgreSQL Global Development Group
5  *
6  * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.147 2010/07/28 04:39:14 petere Exp $
7  */
8 #include "postgres_fe.h"
9 #include "common.h"
10
11 #include <ctype.h>
12 #include <signal.h>
13 #ifndef WIN32
14 #include <unistd.h>                             /* for write() */
15 #else
16 #include <io.h>                                 /* for _write() */
17 #include <win32.h>
18 #endif
19
20 #include "portability/instr_time.h"
21
22 #include "pqsignal.h"
23
24 #include "settings.h"
25 #include "command.h"
26 #include "copy.h"
27 #include "mbprint.h"
28
29
30
31 static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec);
32 static bool command_no_begin(const char *query);
33 static bool is_select_command(const char *query);
34
35 /*
36  * "Safe" wrapper around strdup()
37  */
38 char *
39 pg_strdup(const char *string)
40 {
41         char       *tmp;
42
43         if (!string)
44         {
45                 fprintf(stderr, _("%s: pg_strdup: cannot duplicate null pointer (internal error)\n"),
46                                 pset.progname);
47                 exit(EXIT_FAILURE);
48         }
49         tmp = strdup(string);
50         if (!tmp)
51         {
52                 psql_error("out of memory\n");
53                 exit(EXIT_FAILURE);
54         }
55         return tmp;
56 }
57
58 void *
59 pg_malloc(size_t size)
60 {
61         void       *tmp;
62
63         tmp = malloc(size);
64         if (!tmp)
65         {
66                 psql_error("out of memory\n");
67                 exit(EXIT_FAILURE);
68         }
69         return tmp;
70 }
71
72 void *
73 pg_malloc_zero(size_t size)
74 {
75         void       *tmp;
76
77         tmp = pg_malloc(size);
78         memset(tmp, 0, size);
79         return tmp;
80 }
81
82 void *
83 pg_calloc(size_t nmemb, size_t size)
84 {
85         void       *tmp;
86
87         tmp = calloc(nmemb, size);
88         if (!tmp)
89         {
90                 psql_error("out of memory");
91                 exit(EXIT_FAILURE);
92         }
93         return tmp;
94 }
95
96 /*
97  * setQFout
98  * -- handler for -o command line option and \o command
99  *
100  * Tries to open file fname (or pipe if fname starts with '|')
101  * and stores the file handle in pset)
102  * Upon failure, sets stdout and returns false.
103  */
104 bool
105 setQFout(const char *fname)
106 {
107         bool            status = true;
108
109         /* Close old file/pipe */
110         if (pset.queryFout && pset.queryFout != stdout && pset.queryFout != stderr)
111         {
112                 if (pset.queryFoutPipe)
113                         pclose(pset.queryFout);
114                 else
115                         fclose(pset.queryFout);
116         }
117
118         /* If no filename, set stdout */
119         if (!fname || fname[0] == '\0')
120         {
121                 pset.queryFout = stdout;
122                 pset.queryFoutPipe = false;
123         }
124         else if (*fname == '|')
125         {
126                 pset.queryFout = popen(fname + 1, "w");
127                 pset.queryFoutPipe = true;
128         }
129         else
130         {
131                 pset.queryFout = fopen(fname, "w");
132                 pset.queryFoutPipe = false;
133         }
134
135         if (!(pset.queryFout))
136         {
137                 psql_error("%s: %s\n", fname, strerror(errno));
138                 pset.queryFout = stdout;
139                 pset.queryFoutPipe = false;
140                 status = false;
141         }
142
143         /* Direct signals */
144 #ifndef WIN32
145         pqsignal(SIGPIPE, pset.queryFoutPipe ? SIG_IGN : SIG_DFL);
146 #endif
147
148         return status;
149 }
150
151
152
153 /*
154  * Error reporting for scripts. Errors should look like
155  *       psql:filename:lineno: message
156  *
157  */
158 void
159 psql_error(const char *fmt,...)
160 {
161         va_list         ap;
162
163         fflush(stdout);
164         if (pset.queryFout != stdout)
165                 fflush(pset.queryFout);
166
167         if (pset.inputfile)
168                 fprintf(stderr, "%s:%s:" UINT64_FORMAT ": ", pset.progname, pset.inputfile, pset.lineno);
169         va_start(ap, fmt);
170         vfprintf(stderr, _(fmt), ap);
171         va_end(ap);
172 }
173
174
175
176 /*
177  * for backend Notice messages (INFO, WARNING, etc)
178  */
179 void
180 NoticeProcessor(void *arg, const char *message)
181 {
182         (void) arg;                                     /* not used */
183         psql_error("%s", message);
184 }
185
186
187
188 /*
189  * Code to support query cancellation
190  *
191  * Before we start a query, we enable the SIGINT signal catcher to send a
192  * cancel request to the backend. Note that sending the cancel directly from
193  * the signal handler is safe because PQcancel() is written to make it
194  * so. We use write() to report to stderr because it's better to use simple
195  * facilities in a signal handler.
196  *
197  * On win32, the signal cancelling happens on a separate thread, because
198  * that's how SetConsoleCtrlHandler works. The PQcancel function is safe
199  * for this (unlike PQrequestCancel). However, a CRITICAL_SECTION is required
200  * to protect the PGcancel structure against being changed while the signal
201  * thread is using it.
202  *
203  * SIGINT is supposed to abort all long-running psql operations, not only
204  * database queries.  In most places, this is accomplished by checking
205  * cancel_pressed during long-running loops.  However, that won't work when
206  * blocked on user input (in readline() or fgets()).  In those places, we
207  * set sigint_interrupt_enabled TRUE while blocked, instructing the signal
208  * catcher to longjmp through sigint_interrupt_jmp.  We assume readline and
209  * fgets are coded to handle possible interruption.  (XXX currently this does
210  * not work on win32, so control-C is less useful there)
211  */
212 volatile bool sigint_interrupt_enabled = false;
213
214 sigjmp_buf      sigint_interrupt_jmp;
215
216 static PGcancel *volatile cancelConn = NULL;
217
218 #ifdef WIN32
219 static CRITICAL_SECTION cancelConnLock;
220 #endif
221
222 #define write_stderr(str)       write(fileno(stderr), str, strlen(str))
223
224
225 #ifndef WIN32
226
227 static void
228 handle_sigint(SIGNAL_ARGS)
229 {
230         int                     save_errno = errno;
231         char            errbuf[256];
232
233         /* if we are waiting for input, longjmp out of it */
234         if (sigint_interrupt_enabled)
235         {
236                 sigint_interrupt_enabled = false;
237                 siglongjmp(sigint_interrupt_jmp, 1);
238         }
239
240         /* else, set cancel flag to stop any long-running loops */
241         cancel_pressed = true;
242
243         /* and send QueryCancel if we are processing a database query */
244         if (cancelConn != NULL)
245         {
246                 if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
247                         write_stderr("Cancel request sent\n");
248                 else
249                 {
250                         write_stderr("Could not send cancel request: ");
251                         write_stderr(errbuf);
252                 }
253         }
254
255         errno = save_errno;                     /* just in case the write changed it */
256 }
257
258 void
259 setup_cancel_handler(void)
260 {
261         pqsignal(SIGINT, handle_sigint);
262 }
263 #else                                                   /* WIN32 */
264
265 static BOOL WINAPI
266 consoleHandler(DWORD dwCtrlType)
267 {
268         char            errbuf[256];
269
270         if (dwCtrlType == CTRL_C_EVENT ||
271                 dwCtrlType == CTRL_BREAK_EVENT)
272         {
273                 /*
274                  * Can't longjmp here, because we are in wrong thread :-(
275                  */
276
277                 /* set cancel flag to stop any long-running loops */
278                 cancel_pressed = true;
279
280                 /* and send QueryCancel if we are processing a database query */
281                 EnterCriticalSection(&cancelConnLock);
282                 if (cancelConn != NULL)
283                 {
284                         if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
285                                 write_stderr("Cancel request sent\n");
286                         else
287                         {
288                                 write_stderr("Could not send cancel request: ");
289                                 write_stderr(errbuf);
290                         }
291                 }
292                 LeaveCriticalSection(&cancelConnLock);
293
294                 return TRUE;
295         }
296         else
297                 /* Return FALSE for any signals not being handled */
298                 return FALSE;
299 }
300
301 void
302 setup_cancel_handler(void)
303 {
304         InitializeCriticalSection(&cancelConnLock);
305
306         SetConsoleCtrlHandler(consoleHandler, TRUE);
307 }
308 #endif   /* WIN32 */
309
310
311 /* ConnectionUp
312  *
313  * Returns whether our backend connection is still there.
314  */
315 static bool
316 ConnectionUp(void)
317 {
318         return PQstatus(pset.db) != CONNECTION_BAD;
319 }
320
321
322
323 /* CheckConnection
324  *
325  * Verify that we still have a good connection to the backend, and if not,
326  * see if it can be restored.
327  *
328  * Returns true if either the connection was still there, or it could be
329  * restored successfully; false otherwise.      If, however, there was no
330  * connection and the session is non-interactive, this will exit the program
331  * with a code of EXIT_BADCONN.
332  */
333 static bool
334 CheckConnection(void)
335 {
336         bool            OK;
337
338         OK = ConnectionUp();
339         if (!OK)
340         {
341                 if (!pset.cur_cmd_interactive)
342                 {
343                         psql_error("connection to server was lost\n");
344                         exit(EXIT_BADCONN);
345                 }
346
347                 fputs(_("The connection to the server was lost. Attempting reset: "), stderr);
348                 PQreset(pset.db);
349                 OK = ConnectionUp();
350                 if (!OK)
351                 {
352                         fputs(_("Failed.\n"), stderr);
353                         PQfinish(pset.db);
354                         pset.db = NULL;
355                         ResetCancelConn();
356                         UnsyncVariables();
357                 }
358                 else
359                         fputs(_("Succeeded.\n"), stderr);
360         }
361
362         return OK;
363 }
364
365
366
367 /*
368  * SetCancelConn
369  *
370  * Set cancelConn to point to the current database connection.
371  */
372 void
373 SetCancelConn(void)
374 {
375         PGcancel   *oldCancelConn;
376
377 #ifdef WIN32
378         EnterCriticalSection(&cancelConnLock);
379 #endif
380
381         /* Free the old one if we have one */
382         oldCancelConn = cancelConn;
383         /* be sure handle_sigint doesn't use pointer while freeing */
384         cancelConn = NULL;
385
386         if (oldCancelConn != NULL)
387                 PQfreeCancel(oldCancelConn);
388
389         cancelConn = PQgetCancel(pset.db);
390
391 #ifdef WIN32
392         LeaveCriticalSection(&cancelConnLock);
393 #endif
394 }
395
396
397 /*
398  * ResetCancelConn
399  *
400  * Free the current cancel connection, if any, and set to NULL.
401  */
402 void
403 ResetCancelConn(void)
404 {
405         PGcancel   *oldCancelConn;
406
407 #ifdef WIN32
408         EnterCriticalSection(&cancelConnLock);
409 #endif
410
411         oldCancelConn = cancelConn;
412         /* be sure handle_sigint doesn't use pointer while freeing */
413         cancelConn = NULL;
414
415         if (oldCancelConn != NULL)
416                 PQfreeCancel(oldCancelConn);
417
418 #ifdef WIN32
419         LeaveCriticalSection(&cancelConnLock);
420 #endif
421 }
422
423
424 /*
425  * AcceptResult
426  *
427  * Checks whether a result is valid, giving an error message if necessary;
428  * and ensures that the connection to the backend is still up.
429  *
430  * Returns true for valid result, false for error state.
431  */
432 static bool
433 AcceptResult(const PGresult *result)
434 {
435         bool            OK = true;
436
437         if (!result)
438                 OK = false;
439         else
440                 switch (PQresultStatus(result))
441                 {
442                         case PGRES_COMMAND_OK:
443                         case PGRES_TUPLES_OK:
444                         case PGRES_EMPTY_QUERY:
445                         case PGRES_COPY_IN:
446                         case PGRES_COPY_OUT:
447                                 /* Fine, do nothing */
448                                 break;
449
450                         default:
451                                 OK = false;
452                                 break;
453                 }
454
455         if (!OK)
456         {
457                 const char *error = PQerrorMessage(pset.db);
458
459                 if (strlen(error))
460                         psql_error("%s", error);
461
462                 CheckConnection();
463         }
464
465         return OK;
466 }
467
468
469
470 /*
471  * PSQLexec
472  *
473  * This is the way to send "backdoor" queries (those not directly entered
474  * by the user). It is subject to -E but not -e.
475  *
476  * In autocommit-off mode, a new transaction block is started if start_xact
477  * is true; nothing special is done when start_xact is false.  Typically,
478  * start_xact = false is used for SELECTs and explicit BEGIN/COMMIT commands.
479  *
480  * Caller is responsible for handling the ensuing processing if a COPY
481  * command is sent.
482  *
483  * Note: we don't bother to check PQclientEncoding; it is assumed that no
484  * caller uses this path to issue "SET CLIENT_ENCODING".
485  */
486 PGresult *
487 PSQLexec(const char *query, bool start_xact)
488 {
489         PGresult   *res;
490
491         if (!pset.db)
492         {
493                 psql_error("You are currently not connected to a database.\n");
494                 return NULL;
495         }
496
497         if (pset.echo_hidden != PSQL_ECHO_HIDDEN_OFF)
498         {
499                 printf(_("********* QUERY **********\n"
500                                  "%s\n"
501                                  "**************************\n\n"), query);
502                 fflush(stdout);
503                 if (pset.logfile)
504                 {
505                         fprintf(pset.logfile,
506                                         _("********* QUERY **********\n"
507                                           "%s\n"
508                                           "**************************\n\n"), query);
509                         fflush(pset.logfile);
510                 }
511
512                 if (pset.echo_hidden == PSQL_ECHO_HIDDEN_NOEXEC)
513                         return NULL;
514         }
515
516         SetCancelConn();
517
518         if (start_xact &&
519                 !pset.autocommit &&
520                 PQtransactionStatus(pset.db) == PQTRANS_IDLE)
521         {
522                 res = PQexec(pset.db, "BEGIN");
523                 if (PQresultStatus(res) != PGRES_COMMAND_OK)
524                 {
525                         psql_error("%s", PQerrorMessage(pset.db));
526                         PQclear(res);
527                         ResetCancelConn();
528                         return NULL;
529                 }
530                 PQclear(res);
531         }
532
533         res = PQexec(pset.db, query);
534
535         ResetCancelConn();
536
537         if (!AcceptResult(res))
538         {
539                 PQclear(res);
540                 res = NULL;
541         }
542
543         return res;
544 }
545
546
547
548 /*
549  * PrintNotifications: check for asynchronous notifications, and print them out
550  */
551 static void
552 PrintNotifications(void)
553 {
554         PGnotify   *notify;
555
556         while ((notify = PQnotifies(pset.db)))
557         {
558                 /* for backward compatibility, only show payload if nonempty */
559                 if (notify->extra[0])
560                         fprintf(pset.queryFout, _("Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
561                                         notify->relname, notify->extra, notify->be_pid);
562                 else
563                         fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
564                                         notify->relname, notify->be_pid);
565                 fflush(pset.queryFout);
566                 PQfreemem(notify);
567         }
568 }
569
570
571 /*
572  * PrintQueryTuples: assuming query result is OK, print its tuples
573  *
574  * Returns true if successful, false otherwise.
575  */
576 static bool
577 PrintQueryTuples(const PGresult *results)
578 {
579         printQueryOpt my_popt = pset.popt;
580
581         /* write output to \g argument, if any */
582         if (pset.gfname)
583         {
584                 /* keep this code in sync with ExecQueryUsingCursor */
585                 FILE       *queryFout_copy = pset.queryFout;
586                 bool            queryFoutPipe_copy = pset.queryFoutPipe;
587
588                 pset.queryFout = stdout;        /* so it doesn't get closed */
589
590                 /* open file/pipe */
591                 if (!setQFout(pset.gfname))
592                 {
593                         pset.queryFout = queryFout_copy;
594                         pset.queryFoutPipe = queryFoutPipe_copy;
595                         return false;
596                 }
597
598                 printQuery(results, &my_popt, pset.queryFout, pset.logfile);
599
600                 /* close file/pipe, restore old setting */
601                 setQFout(NULL);
602
603                 pset.queryFout = queryFout_copy;
604                 pset.queryFoutPipe = queryFoutPipe_copy;
605
606                 free(pset.gfname);
607                 pset.gfname = NULL;
608         }
609         else
610                 printQuery(results, &my_popt, pset.queryFout, pset.logfile);
611
612         return true;
613 }
614
615
616 /*
617  * ProcessCopyResult: if command was a COPY FROM STDIN/TO STDOUT, handle it
618  *
619  * Note: Utility function for use by SendQuery() only.
620  *
621  * Returns true if the query executed successfully, false otherwise.
622  */
623 static bool
624 ProcessCopyResult(PGresult *results)
625 {
626         bool            success = false;
627
628         if (!results)
629                 return false;
630
631         switch (PQresultStatus(results))
632         {
633                 case PGRES_TUPLES_OK:
634                 case PGRES_COMMAND_OK:
635                 case PGRES_EMPTY_QUERY:
636                         /* nothing to do here */
637                         success = true;
638                         break;
639
640                 case PGRES_COPY_OUT:
641                         SetCancelConn();
642                         success = handleCopyOut(pset.db, pset.queryFout);
643                         ResetCancelConn();
644                         break;
645
646                 case PGRES_COPY_IN:
647                         SetCancelConn();
648                         success = handleCopyIn(pset.db, pset.cur_cmd_source,
649                                                                    PQbinaryTuples(results));
650                         ResetCancelConn();
651                         break;
652
653                 default:
654                         break;
655         }
656
657         /* may need this to recover from conn loss during COPY */
658         if (!CheckConnection())
659                 return false;
660
661         return success;
662 }
663
664
665 /*
666  * PrintQueryStatus: report command status as required
667  *
668  * Note: Utility function for use by PrintQueryResults() only.
669  */
670 static void
671 PrintQueryStatus(PGresult *results)
672 {
673         char            buf[16];
674
675         if (!pset.quiet)
676         {
677                 if (pset.popt.topt.format == PRINT_HTML)
678                 {
679                         fputs("<p>", pset.queryFout);
680                         html_escaped_print(PQcmdStatus(results), pset.queryFout);
681                         fputs("</p>\n", pset.queryFout);
682                 }
683                 else
684                         fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
685         }
686
687         if (pset.logfile)
688                 fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
689
690         snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
691         SetVariable(pset.vars, "LASTOID", buf);
692 }
693
694
695 /*
696  * PrintQueryResults: print out query results as required
697  *
698  * Note: Utility function for use by SendQuery() only.
699  *
700  * Returns true if the query executed successfully, false otherwise.
701  */
702 static bool
703 PrintQueryResults(PGresult *results)
704 {
705         bool            success = false;
706         const char *cmdstatus;
707
708         if (!results)
709                 return false;
710
711         switch (PQresultStatus(results))
712         {
713                 case PGRES_TUPLES_OK:
714                         /* print the data ... */
715                         success = PrintQueryTuples(results);
716                         /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
717                         cmdstatus = PQcmdStatus(results);
718                         if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
719                                 strncmp(cmdstatus, "UPDATE", 6) == 0 ||
720                                 strncmp(cmdstatus, "DELETE", 6) == 0)
721                                 PrintQueryStatus(results);
722                         break;
723
724                 case PGRES_COMMAND_OK:
725                         PrintQueryStatus(results);
726                         success = true;
727                         break;
728
729                 case PGRES_EMPTY_QUERY:
730                         success = true;
731                         break;
732
733                 case PGRES_COPY_OUT:
734                 case PGRES_COPY_IN:
735                         /* nothing to do here */
736                         success = true;
737                         break;
738
739                 default:
740                         break;
741         }
742
743         fflush(pset.queryFout);
744
745         return success;
746 }
747
748
749 /*
750  * SendQuery: send the query string to the backend
751  * (and print out results)
752  *
753  * Note: This is the "front door" way to send a query. That is, use it to
754  * send queries actually entered by the user. These queries will be subject to
755  * single step mode.
756  * To send "back door" queries (generated by slash commands, etc.) in a
757  * controlled way, use PSQLexec().
758  *
759  * Returns true if the query executed successfully, false otherwise.
760  */
761 bool
762 SendQuery(const char *query)
763 {
764         PGresult   *results;
765         PGTransactionStatusType transaction_status;
766         double          elapsed_msec = 0;
767         bool            OK,
768                                 on_error_rollback_savepoint = false;
769         static bool on_error_rollback_warning = false;
770
771         if (!pset.db)
772         {
773                 psql_error("You are currently not connected to a database.\n");
774                 return false;
775         }
776
777         if (pset.singlestep)
778         {
779                 char            buf[3];
780
781                 printf(_("***(Single step mode: verify command)*******************************************\n"
782                                  "%s\n"
783                                  "***(press return to proceed or enter x and return to cancel)********************\n"),
784                            query);
785                 fflush(stdout);
786                 if (fgets(buf, sizeof(buf), stdin) != NULL)
787                         if (buf[0] == 'x')
788                                 return false;
789         }
790         else if (pset.echo == PSQL_ECHO_QUERIES)
791         {
792                 puts(query);
793                 fflush(stdout);
794         }
795
796         if (pset.logfile)
797         {
798                 fprintf(pset.logfile,
799                                 _("********* QUERY **********\n"
800                                   "%s\n"
801                                   "**************************\n\n"), query);
802                 fflush(pset.logfile);
803         }
804
805         SetCancelConn();
806
807         transaction_status = PQtransactionStatus(pset.db);
808
809         if (transaction_status == PQTRANS_IDLE &&
810                 !pset.autocommit &&
811                 !command_no_begin(query))
812         {
813                 results = PQexec(pset.db, "BEGIN");
814                 if (PQresultStatus(results) != PGRES_COMMAND_OK)
815                 {
816                         psql_error("%s", PQerrorMessage(pset.db));
817                         PQclear(results);
818                         ResetCancelConn();
819                         return false;
820                 }
821                 PQclear(results);
822                 transaction_status = PQtransactionStatus(pset.db);
823         }
824
825         if (transaction_status == PQTRANS_INTRANS &&
826                 pset.on_error_rollback != PSQL_ERROR_ROLLBACK_OFF &&
827                 (pset.cur_cmd_interactive ||
828                  pset.on_error_rollback == PSQL_ERROR_ROLLBACK_ON))
829         {
830                 if (on_error_rollback_warning == false && pset.sversion < 80000)
831                 {
832                         fprintf(stderr, _("The server (version %d.%d) does not support savepoints for ON_ERROR_ROLLBACK.\n"),
833                                         pset.sversion / 10000, (pset.sversion / 100) % 100);
834                         on_error_rollback_warning = true;
835                 }
836                 else
837                 {
838                         results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
839                         if (PQresultStatus(results) != PGRES_COMMAND_OK)
840                         {
841                                 psql_error("%s", PQerrorMessage(pset.db));
842                                 PQclear(results);
843                                 ResetCancelConn();
844                                 return false;
845                         }
846                         PQclear(results);
847                         on_error_rollback_savepoint = true;
848                 }
849         }
850
851         if (pset.fetch_count <= 0 || !is_select_command(query))
852         {
853                 /* Default fetch-it-all-and-print mode */
854                 instr_time      before,
855                                         after;
856
857                 if (pset.timing)
858                         INSTR_TIME_SET_CURRENT(before);
859
860                 results = PQexec(pset.db, query);
861
862                 /* these operations are included in the timing result: */
863                 ResetCancelConn();
864                 OK = (AcceptResult(results) && ProcessCopyResult(results));
865
866                 if (pset.timing)
867                 {
868                         INSTR_TIME_SET_CURRENT(after);
869                         INSTR_TIME_SUBTRACT(after, before);
870                         elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
871                 }
872
873                 /* but printing results isn't: */
874                 if (OK)
875                         OK = PrintQueryResults(results);
876         }
877         else
878         {
879                 /* Fetch-in-segments mode */
880                 OK = ExecQueryUsingCursor(query, &elapsed_msec);
881                 ResetCancelConn();
882                 results = NULL;                 /* PQclear(NULL) does nothing */
883         }
884
885         /* If we made a temporary savepoint, possibly release/rollback */
886         if (on_error_rollback_savepoint)
887         {
888                 const char *svptcmd;
889
890                 transaction_status = PQtransactionStatus(pset.db);
891
892                 if (transaction_status == PQTRANS_INERROR)
893                 {
894                         /* We always rollback on an error */
895                         svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
896                 }
897                 else if (transaction_status != PQTRANS_INTRANS)
898                 {
899                         /* If they are no longer in a transaction, then do nothing */
900                         svptcmd = NULL;
901                 }
902                 else
903                 {
904                         /*
905                          * Do nothing if they are messing with savepoints themselves: If
906                          * the user did RELEASE or ROLLBACK, our savepoint is gone. If
907                          * they issued a SAVEPOINT, releasing ours would remove theirs.
908                          */
909                         if (results &&
910                                 (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
911                                  strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
912                                  strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
913                                 svptcmd = NULL;
914                         else
915                                 svptcmd = "RELEASE pg_psql_temporary_savepoint";
916                 }
917
918                 if (svptcmd)
919                 {
920                         PGresult   *svptres;
921
922                         svptres = PQexec(pset.db, svptcmd);
923                         if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
924                         {
925                                 psql_error("%s", PQerrorMessage(pset.db));
926                                 PQclear(svptres);
927
928                                 PQclear(results);
929                                 ResetCancelConn();
930                                 return false;
931                         }
932                         PQclear(svptres);
933                 }
934         }
935
936         PQclear(results);
937
938         /* Possible microtiming output */
939         if (OK && pset.timing)
940                 printf(_("Time: %.3f ms\n"), elapsed_msec);
941
942         /* check for events that may occur during query execution */
943
944         if (pset.encoding != PQclientEncoding(pset.db) &&
945                 PQclientEncoding(pset.db) >= 0)
946         {
947                 /* track effects of SET CLIENT_ENCODING */
948                 pset.encoding = PQclientEncoding(pset.db);
949                 pset.popt.topt.encoding = pset.encoding;
950                 SetVariable(pset.vars, "ENCODING",
951                                         pg_encoding_to_char(pset.encoding));
952         }
953
954         PrintNotifications();
955
956         return OK;
957 }
958
959
960 /*
961  * ExecQueryUsingCursor: run a SELECT-like query using a cursor
962  *
963  * This feature allows result sets larger than RAM to be dealt with.
964  *
965  * Returns true if the query executed successfully, false otherwise.
966  *
967  * If pset.timing is on, total query time (exclusive of result-printing) is
968  * stored into *elapsed_msec.
969  */
970 static bool
971 ExecQueryUsingCursor(const char *query, double *elapsed_msec)
972 {
973         bool            OK = true;
974         PGresult   *results;
975         PQExpBufferData buf;
976         printQueryOpt my_popt = pset.popt;
977         FILE       *queryFout_copy = pset.queryFout;
978         bool            queryFoutPipe_copy = pset.queryFoutPipe;
979         bool            started_txn = false;
980         bool            did_pager = false;
981         int                     ntuples;
982         char            fetch_cmd[64];
983         instr_time      before,
984                                 after;
985         int                     flush_error;
986
987         *elapsed_msec = 0;
988
989         /* initialize print options for partial table output */
990         my_popt.topt.start_table = true;
991         my_popt.topt.stop_table = false;
992         my_popt.topt.prior_records = 0;
993
994         if (pset.timing)
995                 INSTR_TIME_SET_CURRENT(before);
996
997         /* if we're not in a transaction, start one */
998         if (PQtransactionStatus(pset.db) == PQTRANS_IDLE)
999         {
1000                 results = PQexec(pset.db, "BEGIN");
1001                 OK = AcceptResult(results) &&
1002                         (PQresultStatus(results) == PGRES_COMMAND_OK);
1003                 PQclear(results);
1004                 if (!OK)
1005                         return false;
1006                 started_txn = true;
1007         }
1008
1009         /* Send DECLARE CURSOR */
1010         initPQExpBuffer(&buf);
1011         appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1012                                           query);
1013
1014         results = PQexec(pset.db, buf.data);
1015         OK = AcceptResult(results) &&
1016                 (PQresultStatus(results) == PGRES_COMMAND_OK);
1017         PQclear(results);
1018         termPQExpBuffer(&buf);
1019         if (!OK)
1020                 goto cleanup;
1021
1022         if (pset.timing)
1023         {
1024                 INSTR_TIME_SET_CURRENT(after);
1025                 INSTR_TIME_SUBTRACT(after, before);
1026                 *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1027         }
1028
1029         snprintf(fetch_cmd, sizeof(fetch_cmd),
1030                          "FETCH FORWARD %d FROM _psql_cursor",
1031                          pset.fetch_count);
1032
1033         /* prepare to write output to \g argument, if any */
1034         if (pset.gfname)
1035         {
1036                 /* keep this code in sync with PrintQueryTuples */
1037                 pset.queryFout = stdout;        /* so it doesn't get closed */
1038
1039                 /* open file/pipe */
1040                 if (!setQFout(pset.gfname))
1041                 {
1042                         pset.queryFout = queryFout_copy;
1043                         pset.queryFoutPipe = queryFoutPipe_copy;
1044                         OK = false;
1045                         goto cleanup;
1046                 }
1047         }
1048
1049         /* clear any pre-existing error indication on the output stream */
1050         clearerr(pset.queryFout);
1051
1052         for (;;)
1053         {
1054                 if (pset.timing)
1055                         INSTR_TIME_SET_CURRENT(before);
1056
1057                 /* get FETCH_COUNT tuples at a time */
1058                 results = PQexec(pset.db, fetch_cmd);
1059
1060                 if (pset.timing)
1061                 {
1062                         INSTR_TIME_SET_CURRENT(after);
1063                         INSTR_TIME_SUBTRACT(after, before);
1064                         *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1065                 }
1066
1067                 if (PQresultStatus(results) != PGRES_TUPLES_OK)
1068                 {
1069                         /* shut down pager before printing error message */
1070                         if (did_pager)
1071                         {
1072                                 ClosePager(pset.queryFout);
1073                                 pset.queryFout = queryFout_copy;
1074                                 pset.queryFoutPipe = queryFoutPipe_copy;
1075                                 did_pager = false;
1076                         }
1077
1078                         OK = AcceptResult(results);
1079                         psql_assert(!OK);
1080                         PQclear(results);
1081                         break;
1082                 }
1083
1084                 ntuples = PQntuples(results);
1085
1086                 if (ntuples < pset.fetch_count)
1087                 {
1088                         /* this is the last result set, so allow footer decoration */
1089                         my_popt.topt.stop_table = true;
1090                 }
1091                 else if (pset.queryFout == stdout && !did_pager)
1092                 {
1093                         /*
1094                          * If query requires multiple result sets, hack to ensure that
1095                          * only one pager instance is used for the whole mess
1096                          */
1097                         pset.queryFout = PageOutput(100000, my_popt.topt.pager);
1098                         did_pager = true;
1099                 }
1100
1101                 printQuery(results, &my_popt, pset.queryFout, pset.logfile);
1102
1103                 PQclear(results);
1104
1105                 /* after the first result set, disallow header decoration */
1106                 my_popt.topt.start_table = false;
1107                 my_popt.topt.prior_records += ntuples;
1108
1109                 /*
1110                  * Make sure to flush the output stream, so intermediate results are
1111                  * visible to the client immediately.  We check the results because if
1112                  * the pager dies/exits/etc, there's no sense throwing more data at
1113                  * it.
1114                  */
1115                 flush_error = fflush(pset.queryFout);
1116
1117                 /*
1118                  * Check if we are at the end, if a cancel was pressed, or if there
1119                  * were any errors either trying to flush out the results, or more
1120                  * generally on the output stream at all.  If we hit any errors
1121                  * writing things to the stream, we presume $PAGER has disappeared and
1122                  * stop bothering to pull down more data.
1123                  */
1124                 if (ntuples < pset.fetch_count || cancel_pressed || flush_error ||
1125                         ferror(pset.queryFout))
1126                         break;
1127         }
1128
1129         /* close \g argument file/pipe, restore old setting */
1130         if (pset.gfname)
1131         {
1132                 /* keep this code in sync with PrintQueryTuples */
1133                 setQFout(NULL);
1134
1135                 pset.queryFout = queryFout_copy;
1136                 pset.queryFoutPipe = queryFoutPipe_copy;
1137
1138                 free(pset.gfname);
1139                 pset.gfname = NULL;
1140         }
1141         else if (did_pager)
1142         {
1143                 ClosePager(pset.queryFout);
1144                 pset.queryFout = queryFout_copy;
1145                 pset.queryFoutPipe = queryFoutPipe_copy;
1146         }
1147
1148 cleanup:
1149         if (pset.timing)
1150                 INSTR_TIME_SET_CURRENT(before);
1151
1152         /*
1153          * We try to close the cursor on either success or failure, but on failure
1154          * ignore the result (it's probably just a bleat about being in an aborted
1155          * transaction)
1156          */
1157         results = PQexec(pset.db, "CLOSE _psql_cursor");
1158         if (OK)
1159         {
1160                 OK = AcceptResult(results) &&
1161                         (PQresultStatus(results) == PGRES_COMMAND_OK);
1162         }
1163         PQclear(results);
1164
1165         if (started_txn)
1166         {
1167                 results = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK");
1168                 OK &= AcceptResult(results) &&
1169                         (PQresultStatus(results) == PGRES_COMMAND_OK);
1170                 PQclear(results);
1171         }
1172
1173         if (pset.timing)
1174         {
1175                 INSTR_TIME_SET_CURRENT(after);
1176                 INSTR_TIME_SUBTRACT(after, before);
1177                 *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1178         }
1179
1180         return OK;
1181 }
1182
1183
1184 /*
1185  * Advance the given char pointer over white space and SQL comments.
1186  */
1187 static const char *
1188 skip_white_space(const char *query)
1189 {
1190         int                     cnestlevel = 0; /* slash-star comment nest level */
1191
1192         while (*query)
1193         {
1194                 int                     mblen = PQmblen(query, pset.encoding);
1195
1196                 /*
1197                  * Note: we assume the encoding is a superset of ASCII, so that for
1198                  * example "query[0] == '/'" is meaningful.  However, we do NOT assume
1199                  * that the second and subsequent bytes of a multibyte character
1200                  * couldn't look like ASCII characters; so it is critical to advance
1201                  * by mblen, not 1, whenever we haven't exactly identified the
1202                  * character we are skipping over.
1203                  */
1204                 if (isspace((unsigned char) *query))
1205                         query += mblen;
1206                 else if (query[0] == '/' && query[1] == '*')
1207                 {
1208                         cnestlevel++;
1209                         query += 2;
1210                 }
1211                 else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
1212                 {
1213                         cnestlevel--;
1214                         query += 2;
1215                 }
1216                 else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
1217                 {
1218                         query += 2;
1219
1220                         /*
1221                          * We have to skip to end of line since any slash-star inside the
1222                          * -- comment does NOT start a slash-star comment.
1223                          */
1224                         while (*query)
1225                         {
1226                                 if (*query == '\n')
1227                                 {
1228                                         query++;
1229                                         break;
1230                                 }
1231                                 query += PQmblen(query, pset.encoding);
1232                         }
1233                 }
1234                 else if (cnestlevel > 0)
1235                         query += mblen;
1236                 else
1237                         break;                          /* found first token */
1238         }
1239
1240         return query;
1241 }
1242
1243
1244 /*
1245  * Check whether a command is one of those for which we should NOT start
1246  * a new transaction block (ie, send a preceding BEGIN).
1247  *
1248  * These include the transaction control statements themselves, plus
1249  * certain statements that the backend disallows inside transaction blocks.
1250  */
1251 static bool
1252 command_no_begin(const char *query)
1253 {
1254         int                     wordlen;
1255
1256         /*
1257          * First we must advance over any whitespace and comments.
1258          */
1259         query = skip_white_space(query);
1260
1261         /*
1262          * Check word length (since "beginx" is not "begin").
1263          */
1264         wordlen = 0;
1265         while (isalpha((unsigned char) query[wordlen]))
1266                 wordlen += PQmblen(&query[wordlen], pset.encoding);
1267
1268         /*
1269          * Transaction control commands.  These should include every keyword that
1270          * gives rise to a TransactionStmt in the backend grammar, except for the
1271          * savepoint-related commands.
1272          *
1273          * (We assume that START must be START TRANSACTION, since there is
1274          * presently no other "START foo" command.)
1275          */
1276         if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
1277                 return true;
1278         if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
1279                 return true;
1280         if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
1281                 return true;
1282         if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
1283                 return true;
1284         if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
1285                 return true;
1286         if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
1287                 return true;
1288         if (wordlen == 7 && pg_strncasecmp(query, "prepare", 7) == 0)
1289         {
1290                 /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
1291                 query += wordlen;
1292
1293                 query = skip_white_space(query);
1294
1295                 wordlen = 0;
1296                 while (isalpha((unsigned char) query[wordlen]))
1297                         wordlen += PQmblen(&query[wordlen], pset.encoding);
1298
1299                 if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0)
1300                         return true;
1301                 return false;
1302         }
1303
1304         /*
1305          * Commands not allowed within transactions.  The statements checked for
1306          * here should be exactly those that call PreventTransactionChain() in the
1307          * backend.
1308          */
1309         if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
1310                 return true;
1311         if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
1312         {
1313                 /* CLUSTER with any arguments is allowed in transactions */
1314                 query += wordlen;
1315
1316                 query = skip_white_space(query);
1317
1318                 if (isalpha((unsigned char) query[0]))
1319                         return false;           /* has additional words */
1320                 return true;                    /* it's CLUSTER without arguments */
1321         }
1322
1323         if (wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0)
1324         {
1325                 query += wordlen;
1326
1327                 query = skip_white_space(query);
1328
1329                 wordlen = 0;
1330                 while (isalpha((unsigned char) query[wordlen]))
1331                         wordlen += PQmblen(&query[wordlen], pset.encoding);
1332
1333                 if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
1334                         return true;
1335                 if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
1336                         return true;
1337
1338                 /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
1339                 if (wordlen == 6 && pg_strncasecmp(query, "unique", 6) == 0)
1340                 {
1341                         query += wordlen;
1342
1343                         query = skip_white_space(query);
1344
1345                         wordlen = 0;
1346                         while (isalpha((unsigned char) query[wordlen]))
1347                                 wordlen += PQmblen(&query[wordlen], pset.encoding);
1348                 }
1349
1350                 if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
1351                 {
1352                         query += wordlen;
1353
1354                         query = skip_white_space(query);
1355
1356                         wordlen = 0;
1357                         while (isalpha((unsigned char) query[wordlen]))
1358                                 wordlen += PQmblen(&query[wordlen], pset.encoding);
1359
1360                         if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
1361                                 return true;
1362                 }
1363
1364                 return false;
1365         }
1366
1367         /*
1368          * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
1369          * aren't really valid commands so we don't care much. The other four
1370          * possible matches are correct.
1371          */
1372         if ((wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
1373                 (wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
1374         {
1375                 query += wordlen;
1376
1377                 query = skip_white_space(query);
1378
1379                 wordlen = 0;
1380                 while (isalpha((unsigned char) query[wordlen]))
1381                         wordlen += PQmblen(&query[wordlen], pset.encoding);
1382
1383                 if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
1384                         return true;
1385                 if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
1386                         return true;
1387                 if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
1388                         return true;
1389         }
1390
1391         return false;
1392 }
1393
1394
1395 /*
1396  * Check whether the specified command is a SELECT (or VALUES).
1397  */
1398 static bool
1399 is_select_command(const char *query)
1400 {
1401         int                     wordlen;
1402
1403         /*
1404          * First advance over any whitespace, comments and left parentheses.
1405          */
1406         for (;;)
1407         {
1408                 query = skip_white_space(query);
1409                 if (query[0] == '(')
1410                         query++;
1411                 else
1412                         break;
1413         }
1414
1415         /*
1416          * Check word length (since "selectx" is not "select").
1417          */
1418         wordlen = 0;
1419         while (isalpha((unsigned char) query[wordlen]))
1420                 wordlen += PQmblen(&query[wordlen], pset.encoding);
1421
1422         if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
1423                 return true;
1424
1425         if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
1426                 return true;
1427
1428         return false;
1429 }
1430
1431
1432 /*
1433  * Test if the current user is a database superuser.
1434  *
1435  * Note: this will correctly detect superuserness only with a protocol-3.0
1436  * or newer backend; otherwise it will always say "false".
1437  */
1438 bool
1439 is_superuser(void)
1440 {
1441         const char *val;
1442
1443         if (!pset.db)
1444                 return false;
1445
1446         val = PQparameterStatus(pset.db, "is_superuser");
1447
1448         if (val && strcmp(val, "on") == 0)
1449                 return true;
1450
1451         return false;
1452 }
1453
1454
1455 /*
1456  * Test if the current session uses standard string literals.
1457  *
1458  * Note: With a pre-protocol-3.0 connection this will always say "false",
1459  * which should be the right answer.
1460  */
1461 bool
1462 standard_strings(void)
1463 {
1464         const char *val;
1465
1466         if (!pset.db)
1467                 return false;
1468
1469         val = PQparameterStatus(pset.db, "standard_conforming_strings");
1470
1471         if (val && strcmp(val, "on") == 0)
1472                 return true;
1473
1474         return false;
1475 }
1476
1477
1478 /*
1479  * Return the session user of the current connection.
1480  *
1481  * Note: this will correctly detect the session user only with a
1482  * protocol-3.0 or newer backend; otherwise it will return the
1483  * connection user.
1484  */
1485 const char *
1486 session_username(void)
1487 {
1488         const char *val;
1489
1490         if (!pset.db)
1491                 return NULL;
1492
1493         val = PQparameterStatus(pset.db, "session_authorization");
1494         if (val)
1495                 return val;
1496         else
1497                 return PQuser(pset.db);
1498 }
1499
1500
1501 /* expand_tilde
1502  *
1503  * substitute '~' with HOME or '~username' with username's home dir
1504  *
1505  */
1506 char *
1507 expand_tilde(char **filename)
1508 {
1509         if (!filename || !(*filename))
1510                 return NULL;
1511
1512         /*
1513          * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
1514          * for short versions of long file names, though the tilde is usually
1515          * toward the end, not at the beginning.
1516          */
1517 #ifndef WIN32
1518
1519         /* try tilde expansion */
1520         if (**filename == '~')
1521         {
1522                 char       *fn;
1523                 char            oldp,
1524                                    *p;
1525                 struct passwd *pw;
1526                 char            home[MAXPGPATH];
1527
1528                 fn = *filename;
1529                 *home = '\0';
1530
1531                 p = fn + 1;
1532                 while (*p != '/' && *p != '\0')
1533                         p++;
1534
1535                 oldp = *p;
1536                 *p = '\0';
1537
1538                 if (*(fn + 1) == '\0')
1539                         get_home_path(home);    /* ~ or ~/ only */
1540                 else if ((pw = getpwnam(fn + 1)) != NULL)
1541                         strlcpy(home, pw->pw_dir, sizeof(home));        /* ~user */
1542
1543                 *p = oldp;
1544                 if (strlen(home) != 0)
1545                 {
1546                         char       *newfn;
1547
1548                         newfn = pg_malloc(strlen(home) + strlen(p) + 1);
1549                         strcpy(newfn, home);
1550                         strcat(newfn, p);
1551
1552                         free(fn);
1553                         *filename = newfn;
1554                 }
1555         }
1556 #endif
1557
1558         return *filename;
1559 }