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