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