]> granicus.if.org Git - postgresql/blob - src/bin/psql/common.c
Cause psql to report both the returned data and the command status tag
[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.124 2006/08/13 21:10:04 tgl Exp $
7  */
8 #include "postgres_fe.h"
9 #include "common.h"
10
11 #include <ctype.h>
12 #ifndef HAVE_STRDUP
13 #include <strdup.h>
14 #endif
15 #include <signal.h>
16 #ifndef WIN32
17 #include <sys/time.h>
18 #include <unistd.h>                             /* for write() */
19 #else
20 #include <io.h>                                 /* for _write() */
21 #include <win32.h>
22 #include <sys/timeb.h>                  /* for _ftime() */
23 #endif
24
25 #include "pqsignal.h"
26
27 #include "settings.h"
28 #include "command.h"
29 #include "copy.h"
30 #include "mb/pg_wchar.h"
31
32
33 /* Workarounds for Windows */
34 /* Probably to be moved up the source tree in the future, perhaps to be replaced by
35  * more specific checks like configure-style HAVE_GETTIMEOFDAY macros.
36  */
37 #ifndef WIN32
38
39 typedef struct timeval TimevalStruct;
40
41 #define GETTIMEOFDAY(T) gettimeofday(T, NULL)
42 #define DIFF_MSEC(T, U) \
43         ((((int) ((T)->tv_sec - (U)->tv_sec)) * 1000000.0 + \
44           ((int) ((T)->tv_usec - (U)->tv_usec))) / 1000.0)
45 #else
46
47 typedef struct _timeb TimevalStruct;
48
49 #define GETTIMEOFDAY(T) _ftime(T)
50 #define DIFF_MSEC(T, U) \
51         (((T)->time - (U)->time) * 1000.0 + \
52          ((T)->millitm - (U)->millitm))
53 #endif
54
55
56 static bool command_no_begin(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
287 #else                                                   /* WIN32 */
288
289 static BOOL WINAPI
290 consoleHandler(DWORD dwCtrlType)
291 {
292         char            errbuf[256];
293
294         if (dwCtrlType == CTRL_C_EVENT ||
295                 dwCtrlType == CTRL_BREAK_EVENT)
296         {
297                 /*
298                  * Can't longjmp here, because we are in wrong thread :-(
299                  */
300
301                 /* set cancel flag to stop any long-running loops */
302                 cancel_pressed = true;
303
304                 /* and send QueryCancel if we are processing a database query */
305                 EnterCriticalSection(&cancelConnLock);
306                 if (cancelConn != NULL)
307                 {
308                         if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
309                                 write_stderr("Cancel request sent\n");
310                         else
311                         {
312                                 write_stderr("Could not send cancel request: ");
313                                 write_stderr(errbuf);
314                         }
315                 }
316                 LeaveCriticalSection(&cancelConnLock);
317
318                 return TRUE;
319         }
320         else
321                 /* Return FALSE for any signals not being handled */
322                 return FALSE;
323 }
324
325 void
326 setup_cancel_handler(void)
327 {
328         InitializeCriticalSection(&cancelConnLock);
329
330         SetConsoleCtrlHandler(consoleHandler, TRUE);
331 }
332
333 #endif   /* WIN32 */
334
335
336 /* ConnectionUp
337  *
338  * Returns whether our backend connection is still there.
339  */
340 static bool
341 ConnectionUp(void)
342 {
343         return PQstatus(pset.db) != CONNECTION_BAD;
344 }
345
346
347
348 /* CheckConnection
349  *
350  * Verify that we still have a good connection to the backend, and if not,
351  * see if it can be restored.
352  *
353  * Returns true if either the connection was still there, or it could be
354  * restored successfully; false otherwise.      If, however, there was no
355  * connection and the session is non-interactive, this will exit the program
356  * with a code of EXIT_BADCONN.
357  */
358 static bool
359 CheckConnection(void)
360 {
361         bool            OK;
362
363         OK = ConnectionUp();
364         if (!OK)
365         {
366                 if (!pset.cur_cmd_interactive)
367                 {
368                         psql_error("connection to server was lost\n");
369                         exit(EXIT_BADCONN);
370                 }
371
372                 fputs(_("The connection to the server was lost. Attempting reset: "), stderr);
373                 PQreset(pset.db);
374                 OK = ConnectionUp();
375                 if (!OK)
376                 {
377                         fputs(_("Failed.\n"), stderr);
378                         PQfinish(pset.db);
379                         pset.db = NULL;
380                         ResetCancelConn();
381                         UnsyncVariables();
382                 }
383                 else
384                         fputs(_("Succeeded.\n"), stderr);
385         }
386
387         return OK;
388 }
389
390
391
392 /*
393  * SetCancelConn
394  *
395  * Set cancelConn to point to the current database connection.
396  */
397 void
398 SetCancelConn(void)
399 {
400         PGcancel *oldCancelConn;
401
402 #ifdef WIN32
403         EnterCriticalSection(&cancelConnLock);
404 #endif
405
406         /* Free the old one if we have one */
407         oldCancelConn = cancelConn;
408         /* be sure handle_sigint doesn't use pointer while freeing */
409         cancelConn = NULL;
410
411         if (oldCancelConn != NULL)
412                 PQfreeCancel(oldCancelConn);
413
414         cancelConn = PQgetCancel(pset.db);
415
416 #ifdef WIN32
417         LeaveCriticalSection(&cancelConnLock);
418 #endif
419 }
420
421
422 /*
423  * ResetCancelConn
424  *
425  * Free the current cancel connection, if any, and set to NULL.
426  */
427 void
428 ResetCancelConn(void)
429 {
430         PGcancel *oldCancelConn;
431
432 #ifdef WIN32
433         EnterCriticalSection(&cancelConnLock);
434 #endif
435
436         oldCancelConn = cancelConn;
437         /* be sure handle_sigint doesn't use pointer while freeing */
438         cancelConn = NULL;
439
440         if (oldCancelConn != NULL)
441                 PQfreeCancel(oldCancelConn);
442
443 #ifdef WIN32
444         LeaveCriticalSection(&cancelConnLock);
445 #endif
446 }
447
448
449 /*
450  * AcceptResult
451  *
452  * Checks whether a result is valid, giving an error message if necessary;
453  * resets cancelConn as needed, and ensures that the connection to the backend
454  * is still up.
455  *
456  * Returns true for valid result, false for error state.
457  */
458 static bool
459 AcceptResult(const PGresult *result, const char *query)
460 {
461         bool            OK = true;
462
463         ResetCancelConn();
464
465         if (!result)
466                 OK = false;
467         else
468                 switch (PQresultStatus(result))
469                 {
470                         case PGRES_COMMAND_OK:
471                         case PGRES_TUPLES_OK:
472                         case PGRES_EMPTY_QUERY:
473                         case PGRES_COPY_IN:
474                         case PGRES_COPY_OUT:
475                                 /* Fine, do nothing */
476                                 break;
477
478                         default:
479                                 OK = false;
480                                 break;
481                 }
482
483         if (!OK)
484         {
485                 const char *error = PQerrorMessage(pset.db);
486
487                 if (strlen(error))
488                         psql_error("%s", error);
489
490                 CheckConnection();
491         }
492
493         return OK;
494 }
495
496
497
498 /*
499  * PSQLexec
500  *
501  * This is the way to send "backdoor" queries (those not directly entered
502  * by the user). It is subject to -E but not -e.
503  *
504  * In autocommit-off mode, a new transaction block is started if start_xact
505  * is true; nothing special is done when start_xact is false.  Typically,
506  * start_xact = false is used for SELECTs and explicit BEGIN/COMMIT commands.
507  *
508  * Caller is responsible for handling the ensuing processing if a COPY
509  * command is sent.
510  *
511  * Note: we don't bother to check PQclientEncoding; it is assumed that no
512  * caller uses this path to issue "SET CLIENT_ENCODING".
513  */
514 PGresult *
515 PSQLexec(const char *query, bool start_xact)
516 {
517         PGresult   *res;
518         int                     echo_hidden;
519
520         if (!pset.db)
521         {
522                 psql_error("You are currently not connected to a database.\n");
523                 return NULL;
524         }
525
526         echo_hidden = SwitchVariable(pset.vars, "ECHO_HIDDEN", "noexec", NULL);
527         if (echo_hidden != VAR_NOTSET)
528         {
529                 printf(_("********* QUERY **********\n"
530                                  "%s\n"
531                                  "**************************\n\n"), query);
532                 fflush(stdout);
533                 if (pset.logfile)
534                 {
535                         fprintf(pset.logfile,
536                                         _("********* QUERY **********\n"
537                                           "%s\n"
538                                           "**************************\n\n"), query);
539                         fflush(pset.logfile);
540                 }
541
542                 if (echo_hidden == 1)   /* noexec? */
543                         return NULL;
544         }
545
546         SetCancelConn();
547
548         if (start_xact && PQtransactionStatus(pset.db) == PQTRANS_IDLE &&
549                 !GetVariableBool(pset.vars, "AUTOCOMMIT"))
550         {
551                 res = PQexec(pset.db, "BEGIN");
552                 if (PQresultStatus(res) != PGRES_COMMAND_OK)
553                 {
554                         psql_error("%s", PQerrorMessage(pset.db));
555                         PQclear(res);
556                         ResetCancelConn();
557                         return NULL;
558                 }
559                 PQclear(res);
560         }
561
562         res = PQexec(pset.db, query);
563
564         if (!AcceptResult(res, query) && res)
565         {
566                 PQclear(res);
567                 res = NULL;
568         }
569
570         return res;
571 }
572
573
574
575 /*
576  * PrintNotifications: check for asynchronous notifications, and print them out
577  */
578 static void
579 PrintNotifications(void)
580 {
581         PGnotify   *notify;
582
583         while ((notify = PQnotifies(pset.db)))
584         {
585                 fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
586                                 notify->relname, notify->be_pid);
587                 fflush(pset.queryFout);
588                 PQfreemem(notify);
589         }
590 }
591
592
593 /*
594  * PrintQueryTuples: assuming query result is OK, print its tuples
595  *
596  * Returns true if successful, false otherwise.
597  */
598 static bool
599 PrintQueryTuples(const PGresult *results)
600 {
601         printQueryOpt my_popt = pset.popt;
602
603         /* write output to \g argument, if any */
604         if (pset.gfname)
605         {
606                 FILE       *queryFout_copy = pset.queryFout;
607                 bool            queryFoutPipe_copy = pset.queryFoutPipe;
608
609                 pset.queryFout = stdout;        /* so it doesn't get closed */
610
611                 /* open file/pipe */
612                 if (!setQFout(pset.gfname))
613                 {
614                         pset.queryFout = queryFout_copy;
615                         pset.queryFoutPipe = queryFoutPipe_copy;
616                         return false;
617                 }
618
619                 printQuery(results, &my_popt, pset.queryFout, pset.logfile);
620
621                 /* close file/pipe, restore old setting */
622                 setQFout(NULL);
623
624                 pset.queryFout = queryFout_copy;
625                 pset.queryFoutPipe = queryFoutPipe_copy;
626
627                 free(pset.gfname);
628                 pset.gfname = NULL;
629         }
630         else
631                 printQuery(results, &my_popt, pset.queryFout, pset.logfile);
632
633         return true;
634 }
635
636
637 /*
638  * ProcessCopyResult: if command was a COPY FROM STDIN/TO STDOUT, handle it
639  *
640  * Note: Utility function for use by SendQuery() only.
641  *
642  * Returns true if the query executed successfully, false otherwise.
643  */
644 static bool
645 ProcessCopyResult(PGresult *results)
646 {
647         bool            success = false;
648
649         if (!results)
650                 return false;
651
652         switch (PQresultStatus(results))
653         {
654                 case PGRES_TUPLES_OK:
655                 case PGRES_COMMAND_OK:
656                 case PGRES_EMPTY_QUERY:
657                         /* nothing to do here */
658                         success = true;
659                         break;
660
661                 case PGRES_COPY_OUT:
662                         SetCancelConn();
663                         success = handleCopyOut(pset.db, pset.queryFout);
664                         ResetCancelConn();
665                         break;
666
667                 case PGRES_COPY_IN:
668                         SetCancelConn();
669                         success = handleCopyIn(pset.db, pset.cur_cmd_source,
670                                                                    PQbinaryTuples(results));
671                         ResetCancelConn();
672                         break;
673
674                 default:
675                         break;
676         }
677
678         /* may need this to recover from conn loss during COPY */
679         if (!CheckConnection())
680                 return false;
681
682         return success;
683 }
684
685
686 /*
687  * PrintQueryStatus: report command status as required
688  *
689  * Note: Utility function for use by PrintQueryResults() only.
690  */
691 static void
692 PrintQueryStatus(PGresult *results)
693 {
694         char            buf[16];
695
696         if (!QUIET())
697         {
698                 if (pset.popt.topt.format == PRINT_HTML)
699                 {
700                         fputs("<p>", pset.queryFout);
701                         html_escaped_print(PQcmdStatus(results), pset.queryFout);
702                         fputs("</p>\n", pset.queryFout);
703                 }
704                 else
705                         fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
706         }
707
708         if (pset.logfile)
709                 fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
710
711         snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
712         SetVariable(pset.vars, "LASTOID", buf);
713 }
714
715
716 /*
717  * PrintQueryResults: print out query results as required
718  *
719  * Note: Utility function for use by SendQuery() only.
720  *
721  * Returns true if the query executed successfully, false otherwise.
722  */
723 static bool
724 PrintQueryResults(PGresult *results)
725 {
726         bool            success = false;
727         const char *cmdstatus;
728
729         if (!results)
730                 return false;
731
732         switch (PQresultStatus(results))
733         {
734                 case PGRES_TUPLES_OK:
735                         /* print the data ... */
736                         success = PrintQueryTuples(results);
737                         /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
738                         cmdstatus = PQcmdStatus(results);
739                         if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
740                                 strncmp(cmdstatus, "UPDATE", 6) == 0 ||
741                                 strncmp(cmdstatus, "DELETE", 6) == 0)
742                                 PrintQueryStatus(results);
743                         break;
744
745                 case PGRES_COMMAND_OK:
746                         PrintQueryStatus(results);
747                         success = true;
748                         break;
749
750                 case PGRES_EMPTY_QUERY:
751                         success = true;
752                         break;
753
754                 case PGRES_COPY_OUT:
755                 case PGRES_COPY_IN:
756                         /* nothing to do here */
757                         success = true;
758                         break;
759
760                 default:
761                         break;
762         }
763
764         fflush(pset.queryFout);
765
766         return success;
767 }
768
769
770 /*
771  * SendQuery: send the query string to the backend
772  * (and print out results)
773  *
774  * Note: This is the "front door" way to send a query. That is, use it to
775  * send queries actually entered by the user. These queries will be subject to
776  * single step mode.
777  * To send "back door" queries (generated by slash commands, etc.) in a
778  * controlled way, use PSQLexec().
779  *
780  * Returns true if the query executed successfully, false otherwise.
781  */
782 bool
783 SendQuery(const char *query)
784 {
785         PGresult   *results;
786         TimevalStruct before,
787                                 after;
788         bool            OK,
789                                 on_error_rollback_savepoint = false;
790         PGTransactionStatusType transaction_status;
791         static bool on_error_rollback_warning = false;
792         const char *rollback_str;
793
794         if (!pset.db)
795         {
796                 psql_error("You are currently not connected to a database.\n");
797                 return false;
798         }
799
800         if (GetVariableBool(pset.vars, "SINGLESTEP"))
801         {
802                 char            buf[3];
803
804                 printf(_("***(Single step mode: verify command)*******************************************\n"
805                                  "%s\n"
806                                  "***(press return to proceed or enter x and return to cancel)********************\n"),
807                            query);
808                 fflush(stdout);
809                 if (fgets(buf, sizeof(buf), stdin) != NULL)
810                         if (buf[0] == 'x')
811                                 return false;
812         }
813         else if (VariableEquals(pset.vars, "ECHO", "queries"))
814         {
815                 puts(query);
816                 fflush(stdout);
817         }
818
819         if (pset.logfile)
820         {
821                 fprintf(pset.logfile,
822                                 _("********* QUERY **********\n"
823                                   "%s\n"
824                                   "**************************\n\n"), query);
825                 fflush(pset.logfile);
826         }
827
828         SetCancelConn();
829
830         transaction_status = PQtransactionStatus(pset.db);
831
832         if (transaction_status == PQTRANS_IDLE &&
833                 !GetVariableBool(pset.vars, "AUTOCOMMIT") &&
834                 !command_no_begin(query))
835         {
836                 results = PQexec(pset.db, "BEGIN");
837                 if (PQresultStatus(results) != PGRES_COMMAND_OK)
838                 {
839                         psql_error("%s", PQerrorMessage(pset.db));
840                         PQclear(results);
841                         ResetCancelConn();
842                         return false;
843                 }
844                 PQclear(results);
845                 transaction_status = PQtransactionStatus(pset.db);
846         }
847
848         if (transaction_status == PQTRANS_INTRANS &&
849           (rollback_str = GetVariable(pset.vars, "ON_ERROR_ROLLBACK")) != NULL &&
850         /* !off and !interactive is 'on' */
851                 pg_strcasecmp(rollback_str, "off") != 0 &&
852                 (pset.cur_cmd_interactive ||
853                  pg_strcasecmp(rollback_str, "interactive") != 0))
854         {
855                 if (on_error_rollback_warning == false && pset.sversion < 80000)
856                 {
857                         fprintf(stderr, _("The server version (%d) does not support savepoints for ON_ERROR_ROLLBACK.\n"),
858                                         pset.sversion);
859                         on_error_rollback_warning = true;
860                 }
861                 else
862                 {
863                         results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
864                         if (PQresultStatus(results) != PGRES_COMMAND_OK)
865                         {
866                                 psql_error("%s", PQerrorMessage(pset.db));
867                                 PQclear(results);
868                                 ResetCancelConn();
869                                 return false;
870                         }
871                         PQclear(results);
872                         on_error_rollback_savepoint = true;
873                 }
874         }
875
876         if (pset.timing)
877                 GETTIMEOFDAY(&before);
878
879         results = PQexec(pset.db, query);
880
881         /* these operations are included in the timing result: */
882         OK = (AcceptResult(results, query) && ProcessCopyResult(results));
883
884         if (pset.timing)
885                 GETTIMEOFDAY(&after);
886
887         /* but printing results isn't: */
888         if (OK)
889                 OK = PrintQueryResults(results);
890
891         /* If we made a temporary savepoint, possibly release/rollback */
892         if (on_error_rollback_savepoint)
893         {
894                 PGresult   *svptres;
895
896                 transaction_status = PQtransactionStatus(pset.db);
897
898                 /* We always rollback on an error */
899                 if (transaction_status == PQTRANS_INERROR)
900                         svptres = PQexec(pset.db, "ROLLBACK TO pg_psql_temporary_savepoint");
901                 /* If they are no longer in a transaction, then do nothing */
902                 else if (transaction_status != PQTRANS_INTRANS)
903                         svptres = NULL;
904                 else
905                 {
906                         /*
907                          * Do nothing if they are messing with savepoints themselves: If
908                          * the user did RELEASE or ROLLBACK, our savepoint is gone. If
909                          * they issued a SAVEPOINT, releasing ours would remove theirs.
910                          */
911                         if (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
912                                 strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
913                                 strcmp(PQcmdStatus(results), "ROLLBACK") == 0)
914                                 svptres = NULL;
915                         else
916                                 svptres = PQexec(pset.db, "RELEASE pg_psql_temporary_savepoint");
917                 }
918                 if (svptres && PQresultStatus(svptres) != PGRES_COMMAND_OK)
919                 {
920                         psql_error("%s", PQerrorMessage(pset.db));
921                         PQclear(results);
922                         PQclear(svptres);
923                         ResetCancelConn();
924                         return false;
925                 }
926
927                 PQclear(svptres);
928         }
929
930         PQclear(results);
931
932         /* Possible microtiming output */
933         if (OK && pset.timing)
934                 printf(_("Time: %.3f ms\n"), DIFF_MSEC(&after, &before));
935
936         /* check for events that may occur during query execution */
937
938         if (pset.encoding != PQclientEncoding(pset.db) &&
939                 PQclientEncoding(pset.db) >= 0)
940         {
941                 /* track effects of SET CLIENT_ENCODING */
942                 pset.encoding = PQclientEncoding(pset.db);
943                 pset.popt.topt.encoding = pset.encoding;
944                 SetVariable(pset.vars, "ENCODING",
945                                         pg_encoding_to_char(pset.encoding));
946         }
947
948         PrintNotifications();
949
950         return OK;
951 }
952
953
954 /*
955  * Advance the given char pointer over white space and SQL comments.
956  */
957 static const char *
958 skip_white_space(const char *query)
959 {
960         int                     cnestlevel = 0; /* slash-star comment nest level */
961
962         while (*query)
963         {
964                 int                     mblen = PQmblen(query, pset.encoding);
965
966                 /*
967                  * Note: we assume the encoding is a superset of ASCII, so that for
968                  * example "query[0] == '/'" is meaningful.  However, we do NOT assume
969                  * that the second and subsequent bytes of a multibyte character
970                  * couldn't look like ASCII characters; so it is critical to advance
971                  * by mblen, not 1, whenever we haven't exactly identified the
972                  * character we are skipping over.
973                  */
974                 if (isspace((unsigned char) *query))
975                         query += mblen;
976                 else if (query[0] == '/' && query[1] == '*')
977                 {
978                         cnestlevel++;
979                         query += 2;
980                 }
981                 else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
982                 {
983                         cnestlevel--;
984                         query += 2;
985                 }
986                 else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
987                 {
988                         query += 2;
989
990                         /*
991                          * We have to skip to end of line since any slash-star inside the
992                          * -- comment does NOT start a slash-star comment.
993                          */
994                         while (*query)
995                         {
996                                 if (*query == '\n')
997                                 {
998                                         query++;
999                                         break;
1000                                 }
1001                                 query += PQmblen(query, pset.encoding);
1002                         }
1003                 }
1004                 else if (cnestlevel > 0)
1005                         query += mblen;
1006                 else
1007                         break;                          /* found first token */
1008         }
1009
1010         return query;
1011 }
1012
1013
1014 /*
1015  * Check whether a command is one of those for which we should NOT start
1016  * a new transaction block (ie, send a preceding BEGIN).
1017  *
1018  * These include the transaction control statements themselves, plus
1019  * certain statements that the backend disallows inside transaction blocks.
1020  */
1021 static bool
1022 command_no_begin(const char *query)
1023 {
1024         int                     wordlen;
1025
1026         /*
1027          * First we must advance over any whitespace and comments.
1028          */
1029         query = skip_white_space(query);
1030
1031         /*
1032          * Check word length (since "beginx" is not "begin").
1033          */
1034         wordlen = 0;
1035         while (isalpha((unsigned char) query[wordlen]))
1036                 wordlen += PQmblen(&query[wordlen], pset.encoding);
1037
1038         /*
1039          * Transaction control commands.  These should include every keyword that
1040          * gives rise to a TransactionStmt in the backend grammar, except for the
1041          * savepoint-related commands.
1042          *
1043          * (We assume that START must be START TRANSACTION, since there is
1044          * presently no other "START foo" command.)
1045          */
1046         if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
1047                 return true;
1048         if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
1049                 return true;
1050         if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
1051                 return true;
1052         if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
1053                 return true;
1054         if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
1055                 return true;
1056         if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
1057                 return true;
1058         if (wordlen == 7 && pg_strncasecmp(query, "prepare", 7) == 0)
1059         {
1060                 /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
1061                 query += wordlen;
1062
1063                 query = skip_white_space(query);
1064
1065                 wordlen = 0;
1066                 while (isalpha((unsigned char) query[wordlen]))
1067                         wordlen += PQmblen(&query[wordlen], pset.encoding);
1068
1069                 if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0)
1070                         return true;
1071                 return false;
1072         }
1073
1074         /*
1075          * Commands not allowed within transactions.  The statements checked for
1076          * here should be exactly those that call PreventTransactionChain() in the
1077          * backend.
1078          *
1079          * Note: we are a bit sloppy about CLUSTER, which is transactional in some
1080          * variants but not others.
1081          */
1082         if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
1083                 return true;
1084         if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
1085                 return true;
1086
1087         /*
1088          * Note: these tests will match CREATE SYSTEM, DROP SYSTEM, and REINDEX
1089          * TABLESPACE, which aren't really valid commands so we don't care much.
1090          * The other six possible matches are correct.
1091          */
1092         if ((wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0) ||
1093                 (wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
1094                 (wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
1095         {
1096                 query += wordlen;
1097
1098                 query = skip_white_space(query);
1099
1100                 wordlen = 0;
1101                 while (isalpha((unsigned char) query[wordlen]))
1102                         wordlen += PQmblen(&query[wordlen], pset.encoding);
1103
1104                 if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
1105                         return true;
1106                 if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
1107                         return true;
1108                 if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
1109                         return true;
1110         }
1111
1112         return false;
1113 }
1114
1115
1116 /*
1117  * Test if the current user is a database superuser.
1118  *
1119  * Note: this will correctly detect superuserness only with a protocol-3.0
1120  * or newer backend; otherwise it will always say "false".
1121  */
1122 bool
1123 is_superuser(void)
1124 {
1125         const char *val;
1126
1127         if (!pset.db)
1128                 return false;
1129
1130         val = PQparameterStatus(pset.db, "is_superuser");
1131
1132         if (val && strcmp(val, "on") == 0)
1133                 return true;
1134
1135         return false;
1136 }
1137
1138
1139 /*
1140  * Test if the current session uses standard string literals.
1141  *
1142  * Note: With a pre-protocol-3.0 connection this will always say "false",
1143  * which should be the right answer.
1144  */
1145 bool
1146 standard_strings(void)
1147 {
1148         const char *val;
1149
1150         if (!pset.db)
1151                 return false;
1152
1153         val = PQparameterStatus(pset.db, "standard_conforming_strings");
1154
1155         if (val && strcmp(val, "on") == 0)
1156                 return true;
1157
1158         return false;
1159 }
1160
1161
1162 /*
1163  * Return the session user of the current connection.
1164  *
1165  * Note: this will correctly detect the session user only with a
1166  * protocol-3.0 or newer backend; otherwise it will return the
1167  * connection user.
1168  */
1169 const char *
1170 session_username(void)
1171 {
1172         const char *val;
1173
1174         if (!pset.db)
1175                 return NULL;
1176
1177         val = PQparameterStatus(pset.db, "session_authorization");
1178         if (val)
1179                 return val;
1180         else
1181                 return PQuser(pset.db);
1182 }
1183
1184
1185 /* expand_tilde
1186  *
1187  * substitute '~' with HOME or '~username' with username's home dir
1188  *
1189  */
1190 char *
1191 expand_tilde(char **filename)
1192 {
1193         if (!filename || !(*filename))
1194                 return NULL;
1195
1196         /*
1197          * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
1198          * for short versions of long file names, though the tilde is usually
1199          * toward the end, not at the beginning.
1200          */
1201 #ifndef WIN32
1202
1203         /* try tilde expansion */
1204         if (**filename == '~')
1205         {
1206                 char       *fn;
1207                 char            oldp,
1208                                    *p;
1209                 struct passwd *pw;
1210                 char            home[MAXPGPATH];
1211
1212                 fn = *filename;
1213                 *home = '\0';
1214
1215                 p = fn + 1;
1216                 while (*p != '/' && *p != '\0')
1217                         p++;
1218
1219                 oldp = *p;
1220                 *p = '\0';
1221
1222                 if (*(fn + 1) == '\0')
1223                         get_home_path(home);    /* ~ or ~/ only */
1224                 else if ((pw = getpwnam(fn + 1)) != NULL)
1225                         StrNCpy(home, pw->pw_dir, MAXPGPATH);           /* ~user */
1226
1227                 *p = oldp;
1228                 if (strlen(home) != 0)
1229                 {
1230                         char       *newfn;
1231
1232                         newfn = pg_malloc(strlen(home) + strlen(p) + 1);
1233                         strcpy(newfn, home);
1234                         strcat(newfn, p);
1235
1236                         free(fn);
1237                         *filename = newfn;
1238                 }
1239         }
1240 #endif
1241
1242         return *filename;
1243 }