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