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