Fix obsolete comment regarding FSM truncation.
[PostgreSQL.git] / src / bin / psql / common.c
blob3edf3d1ce10273560c7f0808f3d30b51f70bbcf4
1 /*
2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2008, PostgreSQL Global Development Group
6 * $PostgreSQL$
7 */
8 #include "postgres_fe.h"
9 #include "common.h"
11 #include <ctype.h>
12 #include <signal.h>
13 #ifndef WIN32
14 #include <unistd.h> /* for write() */
15 #else
16 #include <io.h> /* for _write() */
17 #include <win32.h>
18 #endif
20 #include "portability/instr_time.h"
22 #include "pqsignal.h"
24 #include "settings.h"
25 #include "command.h"
26 #include "copy.h"
27 #include "mbprint.h"
31 static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec);
32 static bool command_no_begin(const char *query);
33 static bool is_select_command(const char *query);
36 * "Safe" wrapper around strdup()
38 char *
39 pg_strdup(const char *string)
41 char *tmp;
43 if (!string)
45 fprintf(stderr, _("%s: pg_strdup: cannot duplicate null pointer (internal error)\n"),
46 pset.progname);
47 exit(EXIT_FAILURE);
49 tmp = strdup(string);
50 if (!tmp)
52 psql_error("out of memory\n");
53 exit(EXIT_FAILURE);
55 return tmp;
58 void *
59 pg_malloc(size_t size)
61 void *tmp;
63 tmp = malloc(size);
64 if (!tmp)
66 psql_error("out of memory\n");
67 exit(EXIT_FAILURE);
69 return tmp;
72 void *
73 pg_malloc_zero(size_t size)
75 void *tmp;
77 tmp = pg_malloc(size);
78 memset(tmp, 0, size);
79 return tmp;
82 void *
83 pg_calloc(size_t nmemb, size_t size)
85 void *tmp;
87 tmp = calloc(nmemb, size);
88 if (!tmp)
90 psql_error("out of memory");
91 exit(EXIT_FAILURE);
93 return tmp;
97 * setQFout
98 * -- handler for -o command line option and \o command
100 * Tries to open file fname (or pipe if fname starts with '|')
101 * and stores the file handle in pset)
102 * Upon failure, sets stdout and returns false.
104 bool
105 setQFout(const char *fname)
107 bool status = true;
109 /* Close old file/pipe */
110 if (pset.queryFout && pset.queryFout != stdout && pset.queryFout != stderr)
112 if (pset.queryFoutPipe)
113 pclose(pset.queryFout);
114 else
115 fclose(pset.queryFout);
118 /* If no filename, set stdout */
119 if (!fname || fname[0] == '\0')
121 pset.queryFout = stdout;
122 pset.queryFoutPipe = false;
124 else if (*fname == '|')
126 pset.queryFout = popen(fname + 1, "w");
127 pset.queryFoutPipe = true;
129 else
131 pset.queryFout = fopen(fname, "w");
132 pset.queryFoutPipe = false;
135 if (!(pset.queryFout))
137 psql_error("%s: %s\n", fname, strerror(errno));
138 pset.queryFout = stdout;
139 pset.queryFoutPipe = false;
140 status = false;
143 /* Direct signals */
144 #ifndef WIN32
145 pqsignal(SIGPIPE, pset.queryFoutPipe ? SIG_IGN : SIG_DFL);
146 #endif
148 return status;
154 * Error reporting for scripts. Errors should look like
155 * psql:filename:lineno: message
158 void
159 psql_error(const char *fmt,...)
161 va_list ap;
163 fflush(stdout);
164 if (pset.queryFout != stdout)
165 fflush(pset.queryFout);
167 if (pset.inputfile)
168 fprintf(stderr, "%s:%s:" UINT64_FORMAT ": ", pset.progname, pset.inputfile, pset.lineno);
169 va_start(ap, fmt);
170 vfprintf(stderr, _(fmt), ap);
171 va_end(ap);
177 * for backend Notice messages (INFO, WARNING, etc)
179 void
180 NoticeProcessor(void *arg, const char *message)
182 (void) arg; /* not used */
183 psql_error("%s", message);
189 * Code to support query cancellation
191 * Before we start a query, we enable the SIGINT signal catcher to send a
192 * cancel request to the backend. Note that sending the cancel directly from
193 * the signal handler is safe because PQcancel() is written to make it
194 * so. We use write() to report to stderr because it's better to use simple
195 * facilities in a signal handler.
197 * On win32, the signal cancelling happens on a separate thread, because
198 * that's how SetConsoleCtrlHandler works. The PQcancel function is safe
199 * for this (unlike PQrequestCancel). However, a CRITICAL_SECTION is required
200 * to protect the PGcancel structure against being changed while the signal
201 * thread is using it.
203 * SIGINT is supposed to abort all long-running psql operations, not only
204 * database queries. In most places, this is accomplished by checking
205 * cancel_pressed during long-running loops. However, that won't work when
206 * blocked on user input (in readline() or fgets()). In those places, we
207 * set sigint_interrupt_enabled TRUE while blocked, instructing the signal
208 * catcher to longjmp through sigint_interrupt_jmp. We assume readline and
209 * fgets are coded to handle possible interruption. (XXX currently this does
210 * not work on win32, so control-C is less useful there)
212 volatile bool sigint_interrupt_enabled = false;
214 sigjmp_buf sigint_interrupt_jmp;
216 static PGcancel *volatile cancelConn = NULL;
218 #ifdef WIN32
219 static CRITICAL_SECTION cancelConnLock;
220 #endif
222 #define write_stderr(str) write(fileno(stderr), str, strlen(str))
225 #ifndef WIN32
227 static void
228 handle_sigint(SIGNAL_ARGS)
230 int save_errno = errno;
231 char errbuf[256];
233 /* if we are waiting for input, longjmp out of it */
234 if (sigint_interrupt_enabled)
236 sigint_interrupt_enabled = false;
237 siglongjmp(sigint_interrupt_jmp, 1);
240 /* else, set cancel flag to stop any long-running loops */
241 cancel_pressed = true;
243 /* and send QueryCancel if we are processing a database query */
244 if (cancelConn != NULL)
246 if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
247 write_stderr("Cancel request sent\n");
248 else
250 write_stderr("Could not send cancel request: ");
251 write_stderr(errbuf);
255 errno = save_errno; /* just in case the write changed it */
258 void
259 setup_cancel_handler(void)
261 pqsignal(SIGINT, handle_sigint);
263 #else /* WIN32 */
265 static BOOL WINAPI
266 consoleHandler(DWORD dwCtrlType)
268 char errbuf[256];
270 if (dwCtrlType == CTRL_C_EVENT ||
271 dwCtrlType == CTRL_BREAK_EVENT)
274 * Can't longjmp here, because we are in wrong thread :-(
277 /* set cancel flag to stop any long-running loops */
278 cancel_pressed = true;
280 /* and send QueryCancel if we are processing a database query */
281 EnterCriticalSection(&cancelConnLock);
282 if (cancelConn != NULL)
284 if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
285 write_stderr("Cancel request sent\n");
286 else
288 write_stderr("Could not send cancel request: ");
289 write_stderr(errbuf);
292 LeaveCriticalSection(&cancelConnLock);
294 return TRUE;
296 else
297 /* Return FALSE for any signals not being handled */
298 return FALSE;
301 void
302 setup_cancel_handler(void)
304 InitializeCriticalSection(&cancelConnLock);
306 SetConsoleCtrlHandler(consoleHandler, TRUE);
308 #endif /* WIN32 */
311 /* ConnectionUp
313 * Returns whether our backend connection is still there.
315 static bool
316 ConnectionUp(void)
318 return PQstatus(pset.db) != CONNECTION_BAD;
323 /* CheckConnection
325 * Verify that we still have a good connection to the backend, and if not,
326 * see if it can be restored.
328 * Returns true if either the connection was still there, or it could be
329 * restored successfully; false otherwise. If, however, there was no
330 * connection and the session is non-interactive, this will exit the program
331 * with a code of EXIT_BADCONN.
333 static bool
334 CheckConnection(void)
336 bool OK;
338 OK = ConnectionUp();
339 if (!OK)
341 if (!pset.cur_cmd_interactive)
343 psql_error("connection to server was lost\n");
344 exit(EXIT_BADCONN);
347 fputs(_("The connection to the server was lost. Attempting reset: "), stderr);
348 PQreset(pset.db);
349 OK = ConnectionUp();
350 if (!OK)
352 fputs(_("Failed.\n"), stderr);
353 PQfinish(pset.db);
354 pset.db = NULL;
355 ResetCancelConn();
356 UnsyncVariables();
358 else
359 fputs(_("Succeeded.\n"), stderr);
362 return OK;
368 * SetCancelConn
370 * Set cancelConn to point to the current database connection.
372 void
373 SetCancelConn(void)
375 PGcancel *oldCancelConn;
377 #ifdef WIN32
378 EnterCriticalSection(&cancelConnLock);
379 #endif
381 /* Free the old one if we have one */
382 oldCancelConn = cancelConn;
383 /* be sure handle_sigint doesn't use pointer while freeing */
384 cancelConn = NULL;
386 if (oldCancelConn != NULL)
387 PQfreeCancel(oldCancelConn);
389 cancelConn = PQgetCancel(pset.db);
391 #ifdef WIN32
392 LeaveCriticalSection(&cancelConnLock);
393 #endif
398 * ResetCancelConn
400 * Free the current cancel connection, if any, and set to NULL.
402 void
403 ResetCancelConn(void)
405 PGcancel *oldCancelConn;
407 #ifdef WIN32
408 EnterCriticalSection(&cancelConnLock);
409 #endif
411 oldCancelConn = cancelConn;
412 /* be sure handle_sigint doesn't use pointer while freeing */
413 cancelConn = NULL;
415 if (oldCancelConn != NULL)
416 PQfreeCancel(oldCancelConn);
418 #ifdef WIN32
419 LeaveCriticalSection(&cancelConnLock);
420 #endif
425 * AcceptResult
427 * Checks whether a result is valid, giving an error message if necessary;
428 * and ensures that the connection to the backend is still up.
430 * Returns true for valid result, false for error state.
432 static bool
433 AcceptResult(const PGresult *result)
435 bool OK = true;
437 if (!result)
438 OK = false;
439 else
440 switch (PQresultStatus(result))
442 case PGRES_COMMAND_OK:
443 case PGRES_TUPLES_OK:
444 case PGRES_EMPTY_QUERY:
445 case PGRES_COPY_IN:
446 case PGRES_COPY_OUT:
447 /* Fine, do nothing */
448 break;
450 default:
451 OK = false;
452 break;
455 if (!OK)
457 const char *error = PQerrorMessage(pset.db);
459 if (strlen(error))
460 psql_error("%s", error);
462 CheckConnection();
465 return OK;
471 * PSQLexec
473 * This is the way to send "backdoor" queries (those not directly entered
474 * by the user). It is subject to -E but not -e.
476 * In autocommit-off mode, a new transaction block is started if start_xact
477 * is true; nothing special is done when start_xact is false. Typically,
478 * start_xact = false is used for SELECTs and explicit BEGIN/COMMIT commands.
480 * Caller is responsible for handling the ensuing processing if a COPY
481 * command is sent.
483 * Note: we don't bother to check PQclientEncoding; it is assumed that no
484 * caller uses this path to issue "SET CLIENT_ENCODING".
486 PGresult *
487 PSQLexec(const char *query, bool start_xact)
489 PGresult *res;
491 if (!pset.db)
493 psql_error("You are currently not connected to a database.\n");
494 return NULL;
497 if (pset.echo_hidden != PSQL_ECHO_HIDDEN_OFF)
499 printf(_("********* QUERY **********\n"
500 "%s\n"
501 "**************************\n\n"), query);
502 fflush(stdout);
503 if (pset.logfile)
505 fprintf(pset.logfile,
506 _("********* QUERY **********\n"
507 "%s\n"
508 "**************************\n\n"), query);
509 fflush(pset.logfile);
512 if (pset.echo_hidden == PSQL_ECHO_HIDDEN_NOEXEC)
513 return NULL;
516 SetCancelConn();
518 if (start_xact &&
519 !pset.autocommit &&
520 PQtransactionStatus(pset.db) == PQTRANS_IDLE)
522 res = PQexec(pset.db, "BEGIN");
523 if (PQresultStatus(res) != PGRES_COMMAND_OK)
525 psql_error("%s", PQerrorMessage(pset.db));
526 PQclear(res);
527 ResetCancelConn();
528 return NULL;
530 PQclear(res);
533 res = PQexec(pset.db, query);
535 ResetCancelConn();
537 if (!AcceptResult(res))
539 PQclear(res);
540 res = NULL;
543 return res;
549 * PrintNotifications: check for asynchronous notifications, and print them out
551 static void
552 PrintNotifications(void)
554 PGnotify *notify;
556 while ((notify = PQnotifies(pset.db)))
558 fprintf(pset.queryFout, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
559 notify->relname, notify->be_pid);
560 fflush(pset.queryFout);
561 PQfreemem(notify);
567 * PrintQueryTuples: assuming query result is OK, print its tuples
569 * Returns true if successful, false otherwise.
571 static bool
572 PrintQueryTuples(const PGresult *results)
574 printQueryOpt my_popt = pset.popt;
576 /* write output to \g argument, if any */
577 if (pset.gfname)
579 /* keep this code in sync with ExecQueryUsingCursor */
580 FILE *queryFout_copy = pset.queryFout;
581 bool queryFoutPipe_copy = pset.queryFoutPipe;
583 pset.queryFout = stdout; /* so it doesn't get closed */
585 /* open file/pipe */
586 if (!setQFout(pset.gfname))
588 pset.queryFout = queryFout_copy;
589 pset.queryFoutPipe = queryFoutPipe_copy;
590 return false;
593 printQuery(results, &my_popt, pset.queryFout, pset.logfile);
595 /* close file/pipe, restore old setting */
596 setQFout(NULL);
598 pset.queryFout = queryFout_copy;
599 pset.queryFoutPipe = queryFoutPipe_copy;
601 free(pset.gfname);
602 pset.gfname = NULL;
604 else
605 printQuery(results, &my_popt, pset.queryFout, pset.logfile);
607 return true;
612 * ProcessCopyResult: if command was a COPY FROM STDIN/TO STDOUT, handle it
614 * Note: Utility function for use by SendQuery() only.
616 * Returns true if the query executed successfully, false otherwise.
618 static bool
619 ProcessCopyResult(PGresult *results)
621 bool success = false;
623 if (!results)
624 return false;
626 switch (PQresultStatus(results))
628 case PGRES_TUPLES_OK:
629 case PGRES_COMMAND_OK:
630 case PGRES_EMPTY_QUERY:
631 /* nothing to do here */
632 success = true;
633 break;
635 case PGRES_COPY_OUT:
636 SetCancelConn();
637 success = handleCopyOut(pset.db, pset.queryFout);
638 ResetCancelConn();
639 break;
641 case PGRES_COPY_IN:
642 SetCancelConn();
643 success = handleCopyIn(pset.db, pset.cur_cmd_source,
644 PQbinaryTuples(results));
645 ResetCancelConn();
646 break;
648 default:
649 break;
652 /* may need this to recover from conn loss during COPY */
653 if (!CheckConnection())
654 return false;
656 return success;
661 * PrintQueryStatus: report command status as required
663 * Note: Utility function for use by PrintQueryResults() only.
665 static void
666 PrintQueryStatus(PGresult *results)
668 char buf[16];
670 if (!pset.quiet)
672 if (pset.popt.topt.format == PRINT_HTML)
674 fputs("<p>", pset.queryFout);
675 html_escaped_print(PQcmdStatus(results), pset.queryFout);
676 fputs("</p>\n", pset.queryFout);
678 else
679 fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
682 if (pset.logfile)
683 fprintf(pset.logfile, "%s\n", PQcmdStatus(results));
685 snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results));
686 SetVariable(pset.vars, "LASTOID", buf);
691 * PrintQueryResults: print out query results as required
693 * Note: Utility function for use by SendQuery() only.
695 * Returns true if the query executed successfully, false otherwise.
697 static bool
698 PrintQueryResults(PGresult *results)
700 bool success = false;
701 const char *cmdstatus;
703 if (!results)
704 return false;
706 switch (PQresultStatus(results))
708 case PGRES_TUPLES_OK:
709 /* print the data ... */
710 success = PrintQueryTuples(results);
711 /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
712 cmdstatus = PQcmdStatus(results);
713 if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
714 strncmp(cmdstatus, "UPDATE", 6) == 0 ||
715 strncmp(cmdstatus, "DELETE", 6) == 0)
716 PrintQueryStatus(results);
717 break;
719 case PGRES_COMMAND_OK:
720 PrintQueryStatus(results);
721 success = true;
722 break;
724 case PGRES_EMPTY_QUERY:
725 success = true;
726 break;
728 case PGRES_COPY_OUT:
729 case PGRES_COPY_IN:
730 /* nothing to do here */
731 success = true;
732 break;
734 default:
735 break;
738 fflush(pset.queryFout);
740 return success;
745 * SendQuery: send the query string to the backend
746 * (and print out results)
748 * Note: This is the "front door" way to send a query. That is, use it to
749 * send queries actually entered by the user. These queries will be subject to
750 * single step mode.
751 * To send "back door" queries (generated by slash commands, etc.) in a
752 * controlled way, use PSQLexec().
754 * Returns true if the query executed successfully, false otherwise.
756 bool
757 SendQuery(const char *query)
759 PGresult *results;
760 PGTransactionStatusType transaction_status;
761 double elapsed_msec = 0;
762 bool OK,
763 on_error_rollback_savepoint = false;
764 static bool on_error_rollback_warning = false;
766 if (!pset.db)
768 psql_error("You are currently not connected to a database.\n");
769 return false;
772 if (pset.singlestep)
774 char buf[3];
776 printf(_("***(Single step mode: verify command)*******************************************\n"
777 "%s\n"
778 "***(press return to proceed or enter x and return to cancel)********************\n"),
779 query);
780 fflush(stdout);
781 if (fgets(buf, sizeof(buf), stdin) != NULL)
782 if (buf[0] == 'x')
783 return false;
785 else if (pset.echo == PSQL_ECHO_QUERIES)
787 puts(query);
788 fflush(stdout);
791 if (pset.logfile)
793 fprintf(pset.logfile,
794 _("********* QUERY **********\n"
795 "%s\n"
796 "**************************\n\n"), query);
797 fflush(pset.logfile);
800 SetCancelConn();
802 transaction_status = PQtransactionStatus(pset.db);
804 if (transaction_status == PQTRANS_IDLE &&
805 !pset.autocommit &&
806 !command_no_begin(query))
808 results = PQexec(pset.db, "BEGIN");
809 if (PQresultStatus(results) != PGRES_COMMAND_OK)
811 psql_error("%s", PQerrorMessage(pset.db));
812 PQclear(results);
813 ResetCancelConn();
814 return false;
816 PQclear(results);
817 transaction_status = PQtransactionStatus(pset.db);
820 if (transaction_status == PQTRANS_INTRANS &&
821 pset.on_error_rollback != PSQL_ERROR_ROLLBACK_OFF &&
822 (pset.cur_cmd_interactive ||
823 pset.on_error_rollback == PSQL_ERROR_ROLLBACK_ON))
825 if (on_error_rollback_warning == false && pset.sversion < 80000)
827 fprintf(stderr, _("The server version (%d) does not support savepoints for ON_ERROR_ROLLBACK.\n"),
828 pset.sversion);
829 on_error_rollback_warning = true;
831 else
833 results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
834 if (PQresultStatus(results) != PGRES_COMMAND_OK)
836 psql_error("%s", PQerrorMessage(pset.db));
837 PQclear(results);
838 ResetCancelConn();
839 return false;
841 PQclear(results);
842 on_error_rollback_savepoint = true;
846 if (pset.fetch_count <= 0 || !is_select_command(query))
848 /* Default fetch-it-all-and-print mode */
849 instr_time before,
850 after;
852 if (pset.timing)
853 INSTR_TIME_SET_CURRENT(before);
855 results = PQexec(pset.db, query);
857 /* these operations are included in the timing result: */
858 ResetCancelConn();
859 OK = (AcceptResult(results) && ProcessCopyResult(results));
861 if (pset.timing)
863 INSTR_TIME_SET_CURRENT(after);
864 INSTR_TIME_SUBTRACT(after, before);
865 elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
868 /* but printing results isn't: */
869 if (OK)
870 OK = PrintQueryResults(results);
872 else
874 /* Fetch-in-segments mode */
875 OK = ExecQueryUsingCursor(query, &elapsed_msec);
876 ResetCancelConn();
877 results = NULL; /* PQclear(NULL) does nothing */
880 /* If we made a temporary savepoint, possibly release/rollback */
881 if (on_error_rollback_savepoint)
883 const char *svptcmd;
885 transaction_status = PQtransactionStatus(pset.db);
887 if (transaction_status == PQTRANS_INERROR)
889 /* We always rollback on an error */
890 svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint";
892 else if (transaction_status != PQTRANS_INTRANS)
894 /* If they are no longer in a transaction, then do nothing */
895 svptcmd = NULL;
897 else
900 * Do nothing if they are messing with savepoints themselves: If
901 * the user did RELEASE or ROLLBACK, our savepoint is gone. If
902 * they issued a SAVEPOINT, releasing ours would remove theirs.
904 if (results &&
905 (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
906 strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
907 strcmp(PQcmdStatus(results), "ROLLBACK") == 0))
908 svptcmd = NULL;
909 else
910 svptcmd = "RELEASE pg_psql_temporary_savepoint";
913 if (svptcmd)
915 PGresult *svptres;
917 svptres = PQexec(pset.db, svptcmd);
918 if (PQresultStatus(svptres) != PGRES_COMMAND_OK)
920 psql_error("%s", PQerrorMessage(pset.db));
921 PQclear(svptres);
923 PQclear(results);
924 ResetCancelConn();
925 return false;
927 PQclear(svptres);
931 PQclear(results);
933 /* Possible microtiming output */
934 if (OK && pset.timing && !pset.quiet)
935 printf(_("Time: %.3f ms\n"), elapsed_msec);
937 /* check for events that may occur during query execution */
939 if (pset.encoding != PQclientEncoding(pset.db) &&
940 PQclientEncoding(pset.db) >= 0)
942 /* track effects of SET CLIENT_ENCODING */
943 pset.encoding = PQclientEncoding(pset.db);
944 pset.popt.topt.encoding = pset.encoding;
945 SetVariable(pset.vars, "ENCODING",
946 pg_encoding_to_char(pset.encoding));
949 PrintNotifications();
951 return OK;
956 * ExecQueryUsingCursor: run a SELECT-like query using a cursor
958 * This feature allows result sets larger than RAM to be dealt with.
960 * Returns true if the query executed successfully, false otherwise.
962 * If pset.timing is on, total query time (exclusive of result-printing) is
963 * stored into *elapsed_msec.
965 static bool
966 ExecQueryUsingCursor(const char *query, double *elapsed_msec)
968 bool OK = true;
969 PGresult *results;
970 PQExpBufferData buf;
971 printQueryOpt my_popt = pset.popt;
972 FILE *queryFout_copy = pset.queryFout;
973 bool queryFoutPipe_copy = pset.queryFoutPipe;
974 bool started_txn = false;
975 bool did_pager = false;
976 int ntuples;
977 char fetch_cmd[64];
978 instr_time before,
979 after;
981 *elapsed_msec = 0;
983 /* initialize print options for partial table output */
984 my_popt.topt.start_table = true;
985 my_popt.topt.stop_table = false;
986 my_popt.topt.prior_records = 0;
988 if (pset.timing)
989 INSTR_TIME_SET_CURRENT(before);
991 /* if we're not in a transaction, start one */
992 if (PQtransactionStatus(pset.db) == PQTRANS_IDLE)
994 results = PQexec(pset.db, "BEGIN");
995 OK = AcceptResult(results) &&
996 (PQresultStatus(results) == PGRES_COMMAND_OK);
997 PQclear(results);
998 if (!OK)
999 return false;
1000 started_txn = true;
1003 /* Send DECLARE CURSOR */
1004 initPQExpBuffer(&buf);
1005 appendPQExpBuffer(&buf, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1006 query);
1008 results = PQexec(pset.db, buf.data);
1009 OK = AcceptResult(results) &&
1010 (PQresultStatus(results) == PGRES_COMMAND_OK);
1011 PQclear(results);
1012 termPQExpBuffer(&buf);
1013 if (!OK)
1014 goto cleanup;
1016 if (pset.timing)
1018 INSTR_TIME_SET_CURRENT(after);
1019 INSTR_TIME_SUBTRACT(after, before);
1020 *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1023 snprintf(fetch_cmd, sizeof(fetch_cmd),
1024 "FETCH FORWARD %d FROM _psql_cursor",
1025 pset.fetch_count);
1027 /* prepare to write output to \g argument, if any */
1028 if (pset.gfname)
1030 /* keep this code in sync with PrintQueryTuples */
1031 pset.queryFout = stdout; /* so it doesn't get closed */
1033 /* open file/pipe */
1034 if (!setQFout(pset.gfname))
1036 pset.queryFout = queryFout_copy;
1037 pset.queryFoutPipe = queryFoutPipe_copy;
1038 OK = false;
1039 goto cleanup;
1043 for (;;)
1045 if (pset.timing)
1046 INSTR_TIME_SET_CURRENT(before);
1048 /* get FETCH_COUNT tuples at a time */
1049 results = PQexec(pset.db, fetch_cmd);
1051 if (pset.timing)
1053 INSTR_TIME_SET_CURRENT(after);
1054 INSTR_TIME_SUBTRACT(after, before);
1055 *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1058 if (PQresultStatus(results) != PGRES_TUPLES_OK)
1060 /* shut down pager before printing error message */
1061 if (did_pager)
1063 ClosePager(pset.queryFout);
1064 pset.queryFout = queryFout_copy;
1065 pset.queryFoutPipe = queryFoutPipe_copy;
1066 did_pager = false;
1069 OK = AcceptResult(results);
1070 psql_assert(!OK);
1071 PQclear(results);
1072 break;
1075 ntuples = PQntuples(results);
1077 if (ntuples < pset.fetch_count)
1079 /* this is the last result set, so allow footer decoration */
1080 my_popt.topt.stop_table = true;
1082 else if (pset.queryFout == stdout && !did_pager)
1085 * If query requires multiple result sets, hack to ensure that
1086 * only one pager instance is used for the whole mess
1088 pset.queryFout = PageOutput(100000, my_popt.topt.pager);
1089 did_pager = true;
1092 printQuery(results, &my_popt, pset.queryFout, pset.logfile);
1095 * Make sure to flush the output stream, so intermediate results are
1096 * visible to the client immediately.
1098 fflush(pset.queryFout);
1100 /* after the first result set, disallow header decoration */
1101 my_popt.topt.start_table = false;
1102 my_popt.topt.prior_records += ntuples;
1104 PQclear(results);
1106 if (ntuples < pset.fetch_count || cancel_pressed)
1107 break;
1110 /* close \g argument file/pipe, restore old setting */
1111 if (pset.gfname)
1113 /* keep this code in sync with PrintQueryTuples */
1114 setQFout(NULL);
1116 pset.queryFout = queryFout_copy;
1117 pset.queryFoutPipe = queryFoutPipe_copy;
1119 free(pset.gfname);
1120 pset.gfname = NULL;
1122 else if (did_pager)
1124 ClosePager(pset.queryFout);
1125 pset.queryFout = queryFout_copy;
1126 pset.queryFoutPipe = queryFoutPipe_copy;
1129 cleanup:
1130 if (pset.timing)
1131 INSTR_TIME_SET_CURRENT(before);
1134 * We try to close the cursor on either success or failure, but on failure
1135 * ignore the result (it's probably just a bleat about being in an aborted
1136 * transaction)
1138 results = PQexec(pset.db, "CLOSE _psql_cursor");
1139 if (OK)
1141 OK = AcceptResult(results) &&
1142 (PQresultStatus(results) == PGRES_COMMAND_OK);
1144 PQclear(results);
1146 if (started_txn)
1148 results = PQexec(pset.db, OK ? "COMMIT" : "ROLLBACK");
1149 OK &= AcceptResult(results) &&
1150 (PQresultStatus(results) == PGRES_COMMAND_OK);
1151 PQclear(results);
1154 if (pset.timing)
1156 INSTR_TIME_SET_CURRENT(after);
1157 INSTR_TIME_SUBTRACT(after, before);
1158 *elapsed_msec += INSTR_TIME_GET_MILLISEC(after);
1161 return OK;
1166 * Advance the given char pointer over white space and SQL comments.
1168 static const char *
1169 skip_white_space(const char *query)
1171 int cnestlevel = 0; /* slash-star comment nest level */
1173 while (*query)
1175 int mblen = PQmblen(query, pset.encoding);
1178 * Note: we assume the encoding is a superset of ASCII, so that for
1179 * example "query[0] == '/'" is meaningful. However, we do NOT assume
1180 * that the second and subsequent bytes of a multibyte character
1181 * couldn't look like ASCII characters; so it is critical to advance
1182 * by mblen, not 1, whenever we haven't exactly identified the
1183 * character we are skipping over.
1185 if (isspace((unsigned char) *query))
1186 query += mblen;
1187 else if (query[0] == '/' && query[1] == '*')
1189 cnestlevel++;
1190 query += 2;
1192 else if (cnestlevel > 0 && query[0] == '*' && query[1] == '/')
1194 cnestlevel--;
1195 query += 2;
1197 else if (cnestlevel == 0 && query[0] == '-' && query[1] == '-')
1199 query += 2;
1202 * We have to skip to end of line since any slash-star inside the
1203 * -- comment does NOT start a slash-star comment.
1205 while (*query)
1207 if (*query == '\n')
1209 query++;
1210 break;
1212 query += PQmblen(query, pset.encoding);
1215 else if (cnestlevel > 0)
1216 query += mblen;
1217 else
1218 break; /* found first token */
1221 return query;
1226 * Check whether a command is one of those for which we should NOT start
1227 * a new transaction block (ie, send a preceding BEGIN).
1229 * These include the transaction control statements themselves, plus
1230 * certain statements that the backend disallows inside transaction blocks.
1232 static bool
1233 command_no_begin(const char *query)
1235 int wordlen;
1238 * First we must advance over any whitespace and comments.
1240 query = skip_white_space(query);
1243 * Check word length (since "beginx" is not "begin").
1245 wordlen = 0;
1246 while (isalpha((unsigned char) query[wordlen]))
1247 wordlen += PQmblen(&query[wordlen], pset.encoding);
1250 * Transaction control commands. These should include every keyword that
1251 * gives rise to a TransactionStmt in the backend grammar, except for the
1252 * savepoint-related commands.
1254 * (We assume that START must be START TRANSACTION, since there is
1255 * presently no other "START foo" command.)
1257 if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
1258 return true;
1259 if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
1260 return true;
1261 if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
1262 return true;
1263 if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
1264 return true;
1265 if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
1266 return true;
1267 if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
1268 return true;
1269 if (wordlen == 7 && pg_strncasecmp(query, "prepare", 7) == 0)
1271 /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
1272 query += wordlen;
1274 query = skip_white_space(query);
1276 wordlen = 0;
1277 while (isalpha((unsigned char) query[wordlen]))
1278 wordlen += PQmblen(&query[wordlen], pset.encoding);
1280 if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0)
1281 return true;
1282 return false;
1286 * Commands not allowed within transactions. The statements checked for
1287 * here should be exactly those that call PreventTransactionChain() in the
1288 * backend.
1290 if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0)
1291 return true;
1292 if (wordlen == 7 && pg_strncasecmp(query, "cluster", 7) == 0)
1294 /* CLUSTER with any arguments is allowed in transactions */
1295 query += wordlen;
1297 query = skip_white_space(query);
1299 if (isalpha((unsigned char) query[0]))
1300 return false; /* has additional words */
1301 return true; /* it's CLUSTER without arguments */
1304 if (wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0)
1306 query += wordlen;
1308 query = skip_white_space(query);
1310 wordlen = 0;
1311 while (isalpha((unsigned char) query[wordlen]))
1312 wordlen += PQmblen(&query[wordlen], pset.encoding);
1314 if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
1315 return true;
1316 if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
1317 return true;
1319 /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
1320 if (wordlen == 6 && pg_strncasecmp(query, "unique", 6) == 0)
1322 query += wordlen;
1324 query = skip_white_space(query);
1326 wordlen = 0;
1327 while (isalpha((unsigned char) query[wordlen]))
1328 wordlen += PQmblen(&query[wordlen], pset.encoding);
1331 if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0)
1333 query += wordlen;
1335 query = skip_white_space(query);
1337 wordlen = 0;
1338 while (isalpha((unsigned char) query[wordlen]))
1339 wordlen += PQmblen(&query[wordlen], pset.encoding);
1341 if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0)
1342 return true;
1345 return false;
1349 * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
1350 * aren't really valid commands so we don't care much. The other four
1351 * possible matches are correct.
1353 if ((wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) ||
1354 (wordlen == 7 && pg_strncasecmp(query, "reindex", 7) == 0))
1356 query += wordlen;
1358 query = skip_white_space(query);
1360 wordlen = 0;
1361 while (isalpha((unsigned char) query[wordlen]))
1362 wordlen += PQmblen(&query[wordlen], pset.encoding);
1364 if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0)
1365 return true;
1366 if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0)
1367 return true;
1368 if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0)
1369 return true;
1372 return false;
1377 * Check whether the specified command is a SELECT (or VALUES).
1379 static bool
1380 is_select_command(const char *query)
1382 int wordlen;
1385 * First advance over any whitespace, comments and left parentheses.
1387 for (;;)
1389 query = skip_white_space(query);
1390 if (query[0] == '(')
1391 query++;
1392 else
1393 break;
1397 * Check word length (since "selectx" is not "select").
1399 wordlen = 0;
1400 while (isalpha((unsigned char) query[wordlen]))
1401 wordlen += PQmblen(&query[wordlen], pset.encoding);
1403 if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0)
1404 return true;
1406 if (wordlen == 6 && pg_strncasecmp(query, "values", 6) == 0)
1407 return true;
1409 return false;
1414 * Test if the current user is a database superuser.
1416 * Note: this will correctly detect superuserness only with a protocol-3.0
1417 * or newer backend; otherwise it will always say "false".
1419 bool
1420 is_superuser(void)
1422 const char *val;
1424 if (!pset.db)
1425 return false;
1427 val = PQparameterStatus(pset.db, "is_superuser");
1429 if (val && strcmp(val, "on") == 0)
1430 return true;
1432 return false;
1437 * Test if the current session uses standard string literals.
1439 * Note: With a pre-protocol-3.0 connection this will always say "false",
1440 * which should be the right answer.
1442 bool
1443 standard_strings(void)
1445 const char *val;
1447 if (!pset.db)
1448 return false;
1450 val = PQparameterStatus(pset.db, "standard_conforming_strings");
1452 if (val && strcmp(val, "on") == 0)
1453 return true;
1455 return false;
1460 * Return the session user of the current connection.
1462 * Note: this will correctly detect the session user only with a
1463 * protocol-3.0 or newer backend; otherwise it will return the
1464 * connection user.
1466 const char *
1467 session_username(void)
1469 const char *val;
1471 if (!pset.db)
1472 return NULL;
1474 val = PQparameterStatus(pset.db, "session_authorization");
1475 if (val)
1476 return val;
1477 else
1478 return PQuser(pset.db);
1482 /* expand_tilde
1484 * substitute '~' with HOME or '~username' with username's home dir
1487 char *
1488 expand_tilde(char **filename)
1490 if (!filename || !(*filename))
1491 return NULL;
1494 * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
1495 * for short versions of long file names, though the tilde is usually
1496 * toward the end, not at the beginning.
1498 #ifndef WIN32
1500 /* try tilde expansion */
1501 if (**filename == '~')
1503 char *fn;
1504 char oldp,
1506 struct passwd *pw;
1507 char home[MAXPGPATH];
1509 fn = *filename;
1510 *home = '\0';
1512 p = fn + 1;
1513 while (*p != '/' && *p != '\0')
1514 p++;
1516 oldp = *p;
1517 *p = '\0';
1519 if (*(fn + 1) == '\0')
1520 get_home_path(home); /* ~ or ~/ only */
1521 else if ((pw = getpwnam(fn + 1)) != NULL)
1522 strlcpy(home, pw->pw_dir, sizeof(home)); /* ~user */
1524 *p = oldp;
1525 if (strlen(home) != 0)
1527 char *newfn;
1529 newfn = pg_malloc(strlen(home) + strlen(p) + 1);
1530 strcpy(newfn, home);
1531 strcat(newfn, p);
1533 free(fn);
1534 *filename = newfn;
1537 #endif
1539 return *filename;