2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2003, PostgreSQL Global Development Group
6 * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.88 2004/08/18 02:59:11 momjian Exp $
8 #include "postgres_fe.h"
18 #include <unistd.h> /* for write() */
21 #include <io.h> /* for _write() */
23 #include <sys/timeb.h> /* for _ftime() */
30 #include "variables.h"
36 #include "mb/pg_wchar.h"
39 /* Workarounds for Windows */
40 /* Probably to be moved up the source tree in the future, perhaps to be replaced by
41 * more specific checks like configure-style HAVE_GETTIMEOFDAY macros.
45 typedef struct timeval TimevalStruct;
47 #define GETTIMEOFDAY(T) gettimeofday(T, NULL)
48 #define DIFF_MSEC(T, U) \
49 ((((int) ((T)->tv_sec - (U)->tv_sec)) * 1000000.0 + \
50 ((int) ((T)->tv_usec - (U)->tv_usec))) / 1000.0)
54 typedef struct _timeb TimevalStruct;
56 #define GETTIMEOFDAY(T) _ftime(T)
57 #define DIFF_MSEC(T, U) \
58 (((T)->time - (U)->time) * 1000.0 + \
59 ((T)->millitm - (U)->millitm))
63 extern bool prompt_state;
66 static bool is_transact_command(const char *query);
70 * "Safe" wrapper around strdup()
73 pg_strdup(const char *string)
79 fprintf(stderr, gettext("%s: xstrdup: cannot duplicate null pointer (internal error)\n"),
86 psql_error("out of memory\n");
93 pg_malloc(size_t size)
100 psql_error("out of memory\n");
107 pg_malloc_zero(size_t size)
111 tmp = pg_malloc(size);
112 memset(tmp, 0, size);
117 pg_calloc(size_t nmemb, size_t size)
121 tmp = calloc(nmemb, size);
124 psql_error("out of memory");
132 * -- handler for -o command line option and \o command
134 * Tries to open file fname (or pipe if fname starts with '|')
135 * and stores the file handle in pset)
136 * Upon failure, sets stdout and returns false.
139 setQFout(const char *fname)
143 /* Close old file/pipe */
144 if (pset.queryFout && pset.queryFout != stdout && pset.queryFout != stderr)
146 if (pset.queryFoutPipe)
147 pclose(pset.queryFout);
149 fclose(pset.queryFout);
152 /* If no filename, set stdout */
153 if (!fname || fname[0] == '\0')
155 pset.queryFout = stdout;
156 pset.queryFoutPipe = false;
158 else if (*fname == '|')
160 pset.queryFout = popen(fname + 1, "w");
161 pset.queryFoutPipe = true;
165 pset.queryFout = fopen(fname, "w");
166 pset.queryFoutPipe = false;
169 if (!(pset.queryFout))
171 psql_error("%s: %s\n", fname, strerror(errno));
172 pset.queryFout = stdout;
173 pset.queryFoutPipe = false;
179 pqsignal(SIGPIPE, pset.queryFoutPipe ? SIG_IGN : SIG_DFL);
188 * Error reporting for scripts. Errors should look like
189 * psql:filename:lineno: message
193 psql_error(const char *fmt,...)
198 if (pset.queryFout != stdout)
199 fflush(pset.queryFout);
202 fprintf(stderr, "%s:%s:%u: ", pset.progname, pset.inputfile, pset.lineno);
204 vfprintf(stderr, gettext(fmt), ap);
211 * for backend Notice messages (INFO, WARNING, etc)
214 NoticeProcessor(void *arg, const char *message)
216 (void) arg; /* not used */
217 psql_error("%s", message);
223 * Code to support query cancellation
225 * Before we start a query, we enable a SIGINT signal catcher that sends a
226 * cancel request to the backend. Note that sending the cancel directly from
227 * the signal handler is safe because PQrequestCancel() is written to make it
228 * so. We use write() to print to stdout because it's better to use simple
229 * facilities in a signal handler.
231 static PGconn *volatile cancelConn = NULL;
233 volatile bool cancel_pressed = false;
238 #define write_stderr(String) write(fileno(stderr), String, strlen(String))
241 handle_sigint(SIGNAL_ARGS)
243 int save_errno = errno;
245 /* Don't muck around if prompting for a password. */
249 if (cancelConn == NULL)
250 siglongjmp(main_loop_jmp, 1);
252 cancel_pressed = true;
254 if (PQrequestCancel(cancelConn))
255 write_stderr("Cancel request sent\n");
258 write_stderr("Could not send cancel request: ");
259 write_stderr(PQerrorMessage(cancelConn));
261 errno = save_errno; /* just in case the write changed it */
263 #endif /* not WIN32 */
269 * Returns whether our backend connection is still there.
274 return PQstatus(pset.db) != CONNECTION_BAD;
281 * Verify that we still have a good connection to the backend, and if not,
282 * see if it can be restored.
284 * Returns true if either the connection was still there, or it could be
285 * restored successfully; false otherwise. If, however, there was no
286 * connection and the session is non-interactive, this will exit the program
287 * with a code of EXIT_BADCONN.
290 CheckConnection(void)
297 if (!pset.cur_cmd_interactive)
299 psql_error("connection to server was lost\n");
303 fputs(gettext("The connection to the server was lost. Attempting reset: "), stderr);
308 fputs(gettext("Failed.\n"), stderr);
315 fputs(gettext("Succeeded.\n"), stderr);
326 * Set cancelConn to point to the current database connection.
331 cancelConn = pset.db;
338 * Set cancelConn to NULL. I don't know what this means exactly, but it saves
339 * having to export the variable.
342 ResetCancelConn(void)
349 * on errors, print syntax error position if available.
351 * the query is expected to be in the client encoding.
354 ReportSyntaxErrorPosition(const PGresult *result, const char *query)
356 #define DISPLAY_SIZE 60 /* screen width limit, in screen cols */
357 #define MIN_RIGHT_CUT 10 /* try to keep this far away from EOL */
361 int clen, slen, i, *qidx, *scridx, qoffset, scroffset, ibeg, iend,
364 bool beg_trunc, end_trunc;
367 if (pset.verbosity == PQERRORS_TERSE)
370 sp = PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION);
373 sp = PQresultErrorField(result, PG_DIAG_INTERNAL_POSITION);
375 return; /* no syntax error */
376 query = PQresultErrorField(result, PG_DIAG_INTERNAL_QUERY);
379 return; /* nothing to reference location to */
381 if (sscanf(sp, "%d", &loc) != 1)
383 psql_error("INTERNAL ERROR: unexpected statement position \"%s\"\n",
388 /* Make a writable copy of the query, and a buffer for messages. */
389 wquery = pg_strdup(query);
391 initPQExpBuffer(&msg);
394 * The returned cursor position is measured in logical characters.
395 * Each character might occupy multiple physical bytes in the string,
396 * and in some Far Eastern character sets it might take more than one
397 * screen column as well. We compute the starting byte offset and
398 * starting screen column of each logical character, and store these
399 * in qidx[] and scridx[] respectively.
402 /* we need a safe allocation size... */
403 slen = strlen(query) + 1;
405 qidx = (int *) pg_malloc(slen * sizeof(int));
406 scridx = (int *) pg_malloc(slen * sizeof(int));
410 for (i = 0; query[qoffset] != '\0'; i++)
413 scridx[i] = scroffset;
414 scroffset += PQdsplen(&query[qoffset], pset.encoding);
415 qoffset += PQmblen(&query[qoffset], pset.encoding);
418 scridx[i] = scroffset;
420 psql_assert(clen < slen);
422 /* convert loc to zero-based offset in qidx/scridx arrays */
425 /* do we have something to show? */
426 if (loc >= 0 && loc <= clen)
428 /* input line number of our syntax error. */
430 /* first included char of extract. */
432 /* last-plus-1 included char of extract. */
436 * Replace tabs with spaces in the writable copy. (Later we might
437 * want to think about coping with their variable screen width,
440 * Extract line number and begin and end indexes of line containing
441 * error location. There will not be any newlines or carriage
442 * returns in the selected extract.
444 for (i=0; i<clen; i++)
446 /* character length must be 1 or it's not ASCII */
447 if ((qidx[i+1]-qidx[i]) == 1)
449 if (wquery[qidx[i]] == '\t')
450 wquery[qidx[i]] = ' ';
451 else if (wquery[qidx[i]] == '\r' || wquery[qidx[i]] == '\n')
456 * count lines before loc. Each \r or \n counts
457 * as a line except when \r \n appear together.
459 if (wquery[qidx[i]] == '\r' ||
461 (qidx[i]-qidx[i-1]) != 1 ||
462 wquery[qidx[i-1]] != '\r')
464 /* extract beginning = last line start before loc. */
469 /* set extract end. */
478 /* If the line extracted is too long, we truncate it. */
481 if (scridx[iend]-scridx[ibeg] > DISPLAY_SIZE)
484 * We first truncate right if it is enough. This code might
485 * be off a space or so on enforcing MIN_RIGHT_CUT if there's
486 * a wide character right there, but that should be okay.
488 if (scridx[ibeg]+DISPLAY_SIZE >= scridx[loc]+MIN_RIGHT_CUT)
490 while (scridx[iend]-scridx[ibeg] > DISPLAY_SIZE)
496 /* Truncate right if not too close to loc. */
497 while (scridx[loc]+MIN_RIGHT_CUT < scridx[iend])
503 /* Truncate left if still too long. */
504 while (scridx[iend]-scridx[ibeg] > DISPLAY_SIZE)
512 /* the extract MUST contain the target position! */
513 psql_assert(ibeg<=loc && loc<=iend);
515 /* truncate working copy at desired endpoint */
516 wquery[qidx[iend]] = '\0';
518 /* Begin building the finished message. */
519 printfPQExpBuffer(&msg, gettext("LINE %d: "), loc_line);
521 appendPQExpBufferStr(&msg, "...");
524 * While we have the prefix in the msg buffer, compute its screen
528 for (i = 0; i < msg.len; i += PQmblen(&msg.data[i], pset.encoding))
530 scroffset += PQdsplen(&msg.data[i], pset.encoding);
533 /* Finish and emit the message. */
534 appendPQExpBufferStr(&msg, &wquery[qidx[ibeg]]);
536 appendPQExpBufferStr(&msg, "...");
538 psql_error("%s\n", msg.data);
540 /* Now emit the cursor marker line. */
541 scroffset += scridx[loc] - scridx[ibeg];
542 resetPQExpBuffer(&msg);
543 for (i = 0; i < scroffset; i++)
544 appendPQExpBufferChar(&msg, ' ');
545 appendPQExpBufferChar(&msg, '^');
547 psql_error("%s\n", msg.data);
551 termPQExpBuffer(&msg);
562 * Checks whether a result is valid, giving an error message if necessary;
563 * resets cancelConn as needed, and ensures that the connection to the backend
566 * Returns true for valid result, false for error state.
569 AcceptResult(const PGresult *result, const char *query)
578 switch (PQresultStatus(result))
580 case PGRES_COMMAND_OK:
581 case PGRES_TUPLES_OK:
582 case PGRES_EMPTY_QUERY:
584 /* Fine, do nothing */
588 /* keep cancel connection for copy out state */
599 psql_error("%s", PQerrorMessage(pset.db));
600 ReportSyntaxErrorPosition(result, query);
612 * This is the way to send "backdoor" queries (those not directly entered
613 * by the user). It is subject to -E but not -e.
615 * In autocommit-off mode, a new transaction block is started if start_xact
616 * is true; nothing special is done when start_xact is false. Typically,
617 * start_xact = false is used for SELECTs and explicit BEGIN/COMMIT commands.
619 * Note: we don't bother to check PQclientEncoding; it is assumed that no
620 * caller uses this path to issue "SET CLIENT_ENCODING".
623 PSQLexec(const char *query, bool start_xact)
630 psql_error("You are currently not connected to a database.\n");
634 echo_hidden = SwitchVariable(pset.vars, "ECHO_HIDDEN", "noexec", NULL);
635 if (echo_hidden != VAR_NOTSET)
637 printf("********* QUERY **********\n"
639 "**************************\n\n", query);
642 if (echo_hidden == 1) /* noexec? */
648 if (start_xact && PQtransactionStatus(pset.db) == PQTRANS_IDLE &&
649 !GetVariableBool(pset.vars, "AUTOCOMMIT"))
651 res = PQexec(pset.db, "BEGIN");
652 if (PQresultStatus(res) != PGRES_COMMAND_OK)
654 psql_error("%s", PQerrorMessage(pset.db));
662 res = PQexec(pset.db, query);
664 if (!AcceptResult(res, query) && res)
676 * PrintNotifications: check for asynchronous notifications, and print them out
679 PrintNotifications(void)
683 while ((notify = PQnotifies(pset.db)))
685 fprintf(pset.queryFout, gettext("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
686 notify->relname, notify->be_pid);
687 fflush(pset.queryFout);
694 * PrintQueryTuples: assuming query result is OK, print its tuples
696 * Returns true if successful, false otherwise.
699 PrintQueryTuples(const PGresult *results)
701 /* write output to \g argument, if any */
704 FILE *queryFout_copy = pset.queryFout;
705 bool queryFoutPipe_copy = pset.queryFoutPipe;
707 pset.queryFout = stdout; /* so it doesn't get closed */
710 if (!setQFout(pset.gfname))
712 pset.queryFout = queryFout_copy;
713 pset.queryFoutPipe = queryFoutPipe_copy;
717 printQuery(results, &pset.popt, pset.queryFout);
719 /* close file/pipe, restore old setting */
722 pset.queryFout = queryFout_copy;
723 pset.queryFoutPipe = queryFoutPipe_copy;
729 printQuery(results, &pset.popt, pset.queryFout);
736 * ProcessCopyResult: if command was a COPY FROM STDIN/TO STDOUT, handle it
738 * Note: Utility function for use by SendQuery() only.
740 * Returns true if the query executed successfully, false otherwise.
743 ProcessCopyResult(PGresult *results)
745 bool success = false;
750 switch (PQresultStatus(results))
752 case PGRES_TUPLES_OK:
753 case PGRES_COMMAND_OK:
754 case PGRES_EMPTY_QUERY:
755 /* nothing to do here */
760 success = handleCopyOut(pset.db, pset.queryFout);
764 success = handleCopyIn(pset.db, pset.cur_cmd_source);
771 /* may need this to recover from conn loss during COPY */
772 if (!CheckConnection())
780 * PrintQueryResults: print out query results as required
782 * Note: Utility function for use by SendQuery() only.
784 * Returns true if the query executed successfully, false otherwise.
787 PrintQueryResults(PGresult *results)
789 bool success = false;
794 switch (PQresultStatus(results))
796 case PGRES_TUPLES_OK:
797 success = PrintQueryTuples(results);
800 case PGRES_COMMAND_OK:
805 snprintf(buf, sizeof(buf),
806 "%u", (unsigned int) PQoidValue(results));
809 if (pset.popt.topt.format == PRINT_HTML)
811 fputs("<p>", pset.queryFout);
812 html_escaped_print(PQcmdStatus(results),
814 fputs("</p>\n", pset.queryFout);
817 fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
819 SetVariable(pset.vars, "LASTOID", buf);
823 case PGRES_EMPTY_QUERY:
829 /* nothing to do here */
837 fflush(pset.queryFout);
844 * SendQuery: send the query string to the backend
845 * (and print out results)
847 * Note: This is the "front door" way to send a query. That is, use it to
848 * send queries actually entered by the user. These queries will be subject to
850 * To send "back door" queries (generated by slash commands, etc.) in a
851 * controlled way, use PSQLexec().
853 * Returns true if the query executed successfully, false otherwise.
856 SendQuery(const char *query)
859 TimevalStruct before,
865 psql_error("You are currently not connected to a database.\n");
869 if (GetVariableBool(pset.vars, "SINGLESTEP"))
873 printf(gettext("***(Single step mode: verify command)*******************************************\n"
875 "***(press return to proceed or enter x and return to cancel)********************\n"),
878 if (fgets(buf, sizeof(buf), stdin) != NULL)
882 else if (VariableEquals(pset.vars, "ECHO", "queries"))
890 if (PQtransactionStatus(pset.db) == PQTRANS_IDLE &&
891 !GetVariableBool(pset.vars, "AUTOCOMMIT") &&
892 !is_transact_command(query))
894 results = PQexec(pset.db, "BEGIN");
895 if (PQresultStatus(results) != PGRES_COMMAND_OK)
897 psql_error("%s", PQerrorMessage(pset.db));
906 GETTIMEOFDAY(&before);
908 results = PQexec(pset.db, query);
910 /* these operations are included in the timing result: */
911 OK = (AcceptResult(results, query) && ProcessCopyResult(results));
914 GETTIMEOFDAY(&after);
916 /* but printing results isn't: */
918 OK = PrintQueryResults(results);
922 /* Possible microtiming output */
923 if (OK && pset.timing)
924 printf(gettext("Time: %.3f ms\n"), DIFF_MSEC(&after, &before));
926 /* check for events that may occur during query execution */
928 if (pset.encoding != PQclientEncoding(pset.db) &&
929 PQclientEncoding(pset.db) >= 0)
931 /* track effects of SET CLIENT_ENCODING */
932 pset.encoding = PQclientEncoding(pset.db);
933 pset.popt.topt.encoding = pset.encoding;
934 SetVariable(pset.vars, "ENCODING",
935 pg_encoding_to_char(pset.encoding));
938 PrintNotifications();
944 * check whether a query string begins with BEGIN/COMMIT/ROLLBACK/START XACT
947 is_transact_command(const char *query)
952 * First we must advance over any whitespace and comments.
956 if (isspace((unsigned char) *query))
958 else if (query[0] == '-' && query[1] == '-')
961 while (*query && *query != '\n')
964 else if (query[0] == '/' && query[1] == '*')
969 if (query[0] == '*' && query[1] == '/')
979 break; /* found first token */
983 * Check word length ("beginx" is not "begin").
986 while (isalpha((unsigned char) query[wordlen]))
989 if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
991 if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
993 if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
995 if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
997 if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
999 if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
1007 parse_char(char **buf)
1011 l = strtol(*buf, buf, 0);
1018 * Test if the current user is a database superuser.
1020 * Note: this will correctly detect superuserness only with a protocol-3.0
1021 * or newer backend; otherwise it will always say "false".
1031 val = PQparameterStatus(pset.db, "is_superuser");
1033 if (val && strcmp(val, "on") == 0)
1041 * Return the session user of the current connection.
1043 * Note: this will correctly detect the session user only with a
1044 * protocol-3.0 or newer backend; otherwise it will return the
1048 session_username(void)
1055 val = PQparameterStatus(pset.db, "session_authorization");
1059 return PQuser(pset.db);
1065 * substitute '~' with HOME or '~username' with username's home dir
1069 expand_tilde(char **filename)
1071 if (!filename || !(*filename))
1074 /* MSDOS uses tilde for short versions of long file names, so skip it. */
1077 /* try tilde expansion */
1078 if (**filename == '~')
1084 char home[MAXPGPATH];
1090 while (*p != '/' && *p != '\0')
1096 if (*(fn + 1) == '\0')
1097 get_home_path(home);
1098 else if ((pw = getpwnam(fn + 1)) != NULL)
1099 StrNCpy(home, pw->pw_dir, MAXPGPATH);
1102 if (strlen(home) != 0)
1106 newfn = pg_malloc(strlen(home) + strlen(p) + 1);
1107 strcpy(newfn, home);