2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2008, PostgreSQL Global Development Group
6 * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.190 2008/06/11 10:48:17 heikki Exp $
8 #include "postgres_fe.h"
11 #ifdef __BORLANDC__ /* needed for BCC */
20 #include <sys/types.h> /* for umask() */
21 #include <sys/stat.h> /* for stat() */
22 #include <fcntl.h> /* open() flags */
23 #include <unistd.h> /* for geteuid(), getpid(), stat() */
29 #include <sys/types.h> /* for umask() */
30 #include <sys/stat.h> /* for stat() */
33 #include "portability/instr_time.h"
36 #include "pqexpbuffer.h"
37 #include "dumputils.h"
44 #include "large_obj.h"
49 #include "variables.h"
52 /* functions for use in this file */
53 static backslashResult exec_command(const char *cmd,
54 PsqlScanState scan_state,
55 PQExpBuffer query_buf);
56 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf);
57 static bool do_connect(char *dbname, char *user, char *host, char *port);
58 static bool do_shell(const char *command);
64 * Handles all the different commands that start with '\'.
65 * Ordinarily called by MainLoop().
67 * scan_state is a lexer working state that is set to continue scanning
68 * just after the '\'. The lexer is advanced past the command and all
69 * arguments on return.
71 * 'query_buf' contains the query-so-far, which may be modified by
72 * execution of the backslash command (for example, \r clears it).
73 * query_buf can be NULL if there is no query so far.
75 * Returns a status code indicating what action is desired, see command.h.
80 HandleSlashCmds(PsqlScanState scan_state,
81 PQExpBuffer query_buf)
83 backslashResult status = PSQL_CMD_SKIP_LINE;
87 psql_assert(scan_state);
89 /* Parse off the command name */
90 cmd = psql_scan_slash_command(scan_state);
92 /* And try to execute it */
93 status = exec_command(cmd, scan_state, query_buf);
95 if (status == PSQL_CMD_UNKNOWN)
97 if (pset.cur_cmd_interactive)
98 fprintf(stderr, _("Invalid command \\%s. Try \\? for help.\n"), cmd);
100 psql_error("invalid command \\%s\n", cmd);
101 status = PSQL_CMD_ERROR;
104 if (status != PSQL_CMD_ERROR)
106 /* eat any remaining arguments after a valid command */
107 /* note we suppress evaluation of backticks here */
108 while ((arg = psql_scan_slash_option(scan_state,
109 OT_VERBATIM, NULL, false)))
111 psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
117 /* silently throw away rest of line after an erroneous command */
118 while ((arg = psql_scan_slash_option(scan_state,
119 OT_WHOLE_LINE, NULL, false)))
123 /* if there is a trailing \\, swallow it */
124 psql_scan_slash_command_end(scan_state);
128 /* some commands write to queryFout, so make sure output is sent */
129 fflush(pset.queryFout);
135 * Read and interpret an argument to the \connect slash command.
138 read_connect_arg(PsqlScanState scan_state)
144 * Ideally we should treat the arguments as SQL identifiers. But for
145 * backwards compatibility with 7.2 and older pg_dump files, we have to
146 * take unquoted arguments verbatim (don't downcase them). For now,
147 * double-quoted arguments may be stripped of double quotes (as if SQL
148 * identifiers). By 7.4 or so, pg_dump files can be expected to
149 * double-quote all mixed-case \connect arguments, and then we can get rid
152 result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, "e, true);
160 if (*result == '\0' || strcmp(result, "-") == 0)
168 * Subroutine to actually try to execute a backslash command.
170 static backslashResult
171 exec_command(const char *cmd,
172 PsqlScanState scan_state,
173 PQExpBuffer query_buf)
175 bool success = true; /* indicate here if the command ran ok or
177 backslashResult status = PSQL_CMD_SKIP_LINE;
180 * \a -- toggle field alignment This makes little sense but we keep it
183 if (strcmp(cmd, "a") == 0)
185 if (pset.popt.topt.format != PRINT_ALIGNED)
186 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
188 success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
191 /* \C -- override table title (formerly change HTML caption) */
192 else if (strcmp(cmd, "C") == 0)
194 char *opt = psql_scan_slash_option(scan_state,
195 OT_NORMAL, NULL, true);
197 success = do_pset("title", opt, &pset.popt, pset.quiet);
202 * \c or \connect -- connect to database using the specified parameters.
204 * \c dbname user host port
206 * If any of these parameters are omitted or specified as '-', the current
207 * value of the parameter will be used instead. If the parameter has no
208 * current value, the default value for that parameter will be used. Some
211 * \c - - hst Connect to current database on current port of host
212 * "hst" as current user. \c - usr - prt Connect to current database on
213 * "prt" port of current host as user "usr". \c dbs Connect to
214 * "dbs" database on current port of current host as current user.
216 else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
223 opt1 = read_connect_arg(scan_state);
224 opt2 = read_connect_arg(scan_state);
225 opt3 = read_connect_arg(scan_state);
226 opt4 = read_connect_arg(scan_state);
228 success = do_connect(opt1, opt2, opt3, opt4);
237 else if (strcmp(cmd, "cd") == 0)
239 char *opt = psql_scan_slash_option(scan_state,
240 OT_NORMAL, NULL, true);
250 pw = getpwuid(geteuid());
253 psql_error("could not get home directory: %s\n", strerror(errno));
260 * On Windows, 'cd' without arguments prints the current
261 * directory, so if someone wants to code this here instead...
267 if (chdir(dir) == -1)
269 psql_error("\\%s: could not change directory to \"%s\": %s\n",
270 cmd, dir, strerror(errno));
276 pset.dirname = pg_strdup(dir);
277 canonicalize_path(pset.dirname);
284 else if (pg_strcasecmp(cmd, "copy") == 0)
286 /* Default fetch-it-all-and-print mode */
290 char *opt = psql_scan_slash_option(scan_state,
291 OT_WHOLE_LINE, NULL, false);
294 INSTR_TIME_SET_CURRENT(before);
296 success = do_copy(opt);
298 if (pset.timing && success)
300 INSTR_TIME_SET_CURRENT(after);
301 INSTR_TIME_SUBTRACT(after, before);
302 printf(_("Time: %.3f ms\n"), INSTR_TIME_GET_MILLISEC(after));
309 else if (strcmp(cmd, "copyright") == 0)
313 else if (cmd[0] == 'd')
318 /* We don't do SQLID reduction on the pattern yet */
319 pattern = psql_scan_slash_option(scan_state,
320 OT_NORMAL, NULL, true);
322 show_verbose = strchr(cmd, '+') ? true : false;
329 success = describeTableDetails(pattern, show_verbose);
331 /* standard listing of interesting things */
332 success = listTables("tvs", NULL, show_verbose);
335 success = describeAggregates(pattern, show_verbose);
338 success = describeTablespaces(pattern, show_verbose);
341 success = listConversions(pattern);
344 success = listCasts(pattern);
347 success = objectDescription(pattern);
350 success = listDomains(pattern);
353 success = describeFunctions(pattern, show_verbose);
356 /* no longer distinct from \du */
357 success = describeRoles(pattern, show_verbose);
360 success = do_lo_list();
363 success = listSchemas(pattern, show_verbose);
366 success = describeOperators(pattern);
369 success = permissionsList(pattern);
372 success = describeTypes(pattern, show_verbose);
379 success = listTables(&cmd[1], pattern, show_verbose);
382 success = describeRoles(pattern, show_verbose);
384 case 'F': /* text search subsystem */
389 success = listTSConfigs(pattern, show_verbose);
392 success = listTSParsers(pattern, show_verbose);
395 success = listTSDictionaries(pattern, show_verbose);
398 success = listTSTemplates(pattern, show_verbose);
401 status = PSQL_CMD_UNKNOWN;
407 status = PSQL_CMD_UNKNOWN;
416 * \e or \edit -- edit the current query buffer (or a file and make it the
419 else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
425 psql_error("no query buffer\n");
426 status = PSQL_CMD_ERROR;
430 fname = psql_scan_slash_option(scan_state,
431 OT_NORMAL, NULL, true);
432 expand_tilde(&fname);
434 canonicalize_path(fname);
435 status = do_edit(fname, query_buf) ? PSQL_CMD_NEWEDIT : PSQL_CMD_ERROR;
440 /* \echo and \qecho */
441 else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
445 bool no_newline = false;
449 if (strcmp(cmd, "qecho") == 0)
450 fout = pset.queryFout;
454 while ((value = psql_scan_slash_option(scan_state,
455 OT_NORMAL, "ed, false)))
457 if (!quoted && strcmp(value, "-n") == 0)
473 /* \encoding -- set/show client side encoding */
474 else if (strcmp(cmd, "encoding") == 0)
476 char *encoding = psql_scan_slash_option(scan_state,
477 OT_NORMAL, NULL, false);
482 puts(pg_encoding_to_char(pset.encoding));
487 if (PQsetClientEncoding(pset.db, encoding) == -1)
488 psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
491 /* save encoding info into psql internal data */
492 pset.encoding = PQclientEncoding(pset.db);
493 pset.popt.topt.encoding = pset.encoding;
494 SetVariable(pset.vars, "ENCODING",
495 pg_encoding_to_char(pset.encoding));
501 /* \f -- change field separator */
502 else if (strcmp(cmd, "f") == 0)
504 char *fname = psql_scan_slash_option(scan_state,
505 OT_NORMAL, NULL, false);
507 success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
511 /* \g means send query */
512 else if (strcmp(cmd, "g") == 0)
514 char *fname = psql_scan_slash_option(scan_state,
515 OT_FILEPIPE, NULL, false);
521 expand_tilde(&fname);
522 pset.gfname = pg_strdup(fname);
525 status = PSQL_CMD_SEND;
529 else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
531 char *opt = psql_scan_slash_option(scan_state,
532 OT_WHOLE_LINE, NULL, false);
534 helpSQL(opt, pset.popt.topt.pager);
539 else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
541 if (pset.popt.topt.format != PRINT_HTML)
542 success = do_pset("format", "html", &pset.popt, pset.quiet);
544 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
548 /* \i is include file */
549 else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
551 char *fname = psql_scan_slash_option(scan_state,
552 OT_NORMAL, NULL, true);
556 psql_error("\\%s: missing required argument\n", cmd);
561 expand_tilde(&fname);
562 success = (process_file(fname, false) == EXIT_SUCCESS);
567 /* \l is list databases */
568 else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0)
569 success = listAllDbs(false);
570 else if (strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
571 success = listAllDbs(true);
574 * large object things
576 else if (strncmp(cmd, "lo_", 3) == 0)
581 opt1 = psql_scan_slash_option(scan_state,
582 OT_NORMAL, NULL, true);
583 opt2 = psql_scan_slash_option(scan_state,
584 OT_NORMAL, NULL, true);
586 if (strcmp(cmd + 3, "export") == 0)
590 psql_error("\\%s: missing required argument\n", cmd);
596 success = do_lo_export(opt1, opt2);
600 else if (strcmp(cmd + 3, "import") == 0)
604 psql_error("\\%s: missing required argument\n", cmd);
610 success = do_lo_import(opt1, opt2);
614 else if (strcmp(cmd + 3, "list") == 0)
615 success = do_lo_list();
617 else if (strcmp(cmd + 3, "unlink") == 0)
621 psql_error("\\%s: missing required argument\n", cmd);
625 success = do_lo_unlink(opt1);
629 status = PSQL_CMD_UNKNOWN;
636 /* \o -- set query output */
637 else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
639 char *fname = psql_scan_slash_option(scan_state,
640 OT_FILEPIPE, NULL, true);
642 expand_tilde(&fname);
643 success = setQFout(fname);
647 /* \p prints the current query buffer */
648 else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
650 if (query_buf && query_buf->len > 0)
651 puts(query_buf->data);
652 else if (!pset.quiet)
653 puts(_("Query buffer is empty."));
657 /* \password -- set user password */
658 else if (strcmp(cmd, "password") == 0)
663 pw1 = simple_prompt("Enter new password: ", 100, false);
664 pw2 = simple_prompt("Enter it again: ", 100, false);
666 if (strcmp(pw1, pw2) != 0)
668 fprintf(stderr, _("Passwords didn't match.\n"));
673 char *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true);
675 char *encrypted_password;
680 user = PQuser(pset.db);
682 encrypted_password = PQencryptPassword(pw1, user);
684 if (!encrypted_password)
686 fprintf(stderr, _("Password encryption failed.\n"));
694 initPQExpBuffer(&buf);
695 printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
697 appendStringLiteralConn(&buf, encrypted_password, pset.db);
698 res = PSQLexec(buf.data, false);
699 termPQExpBuffer(&buf);
704 PQfreemem(encrypted_password);
712 /* \prompt -- prompt and set variable */
713 else if (strcmp(cmd, "prompt") == 0)
720 arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
721 arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
725 psql_error("\\%s: missing required argument\n", cmd);
741 result = simple_prompt(prompt_text, 4096, true);
746 fputs(prompt_text, stdout);
749 result = gets_fromFile(stdin);
752 if (!SetVariable(pset.vars, opt, result))
754 psql_error("\\%s: error\n", cmd);
765 /* \pset -- set printing parameters */
766 else if (strcmp(cmd, "pset") == 0)
768 char *opt0 = psql_scan_slash_option(scan_state,
769 OT_NORMAL, NULL, false);
770 char *opt1 = psql_scan_slash_option(scan_state,
771 OT_NORMAL, NULL, false);
775 psql_error("\\%s: missing required argument\n", cmd);
779 success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
786 else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
787 status = PSQL_CMD_TERMINATE;
789 /* reset(clear) the buffer */
790 else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
792 resetPQExpBuffer(query_buf);
793 psql_scan_reset(scan_state);
795 puts(_("Query buffer reset (cleared)."));
798 /* \s save history in a file or show it on the screen */
799 else if (strcmp(cmd, "s") == 0)
801 char *fname = psql_scan_slash_option(scan_state,
802 OT_NORMAL, NULL, true);
804 expand_tilde(&fname);
805 /* This scrolls off the screen when using /dev/tty */
806 success = saveHistory(fname ? fname : DEVTTY, false);
807 if (success && !pset.quiet && fname)
808 printf(gettext("Wrote history to file \"%s/%s\".\n"),
809 pset.dirname ? pset.dirname : ".", fname);
815 /* \set -- generalized set variable/option command */
816 else if (strcmp(cmd, "set") == 0)
818 char *opt0 = psql_scan_slash_option(scan_state,
819 OT_NORMAL, NULL, false);
823 /* list all variables */
824 PrintVariables(pset.vars);
830 * Set variable to the concatenation of the arguments.
835 opt = psql_scan_slash_option(scan_state,
836 OT_NORMAL, NULL, false);
837 newval = pg_strdup(opt ? opt : "");
840 while ((opt = psql_scan_slash_option(scan_state,
841 OT_NORMAL, NULL, false)))
843 newval = realloc(newval, strlen(newval) + strlen(opt) + 1);
846 psql_error("out of memory\n");
853 if (!SetVariable(pset.vars, opt0, newval))
855 psql_error("\\%s: error\n", cmd);
863 /* \t -- turn off headers and row count */
864 else if (strcmp(cmd, "t") == 0)
866 char *opt = psql_scan_slash_option(scan_state,
867 OT_NORMAL, NULL, true);
869 success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
874 /* \T -- define html <table ...> attributes */
875 else if (strcmp(cmd, "T") == 0)
877 char *value = psql_scan_slash_option(scan_state,
878 OT_NORMAL, NULL, false);
880 success = do_pset("tableattr", value, &pset.popt, pset.quiet);
884 /* \timing -- toggle timing of queries */
885 else if (strcmp(cmd, "timing") == 0)
887 char *opt = psql_scan_slash_option(scan_state,
888 OT_NORMAL, NULL, false);
890 pset.timing = ParseVariableBool(opt);
892 pset.timing = !pset.timing;
896 puts(_("Timing is on."));
898 puts(_("Timing is off."));
904 else if (strcmp(cmd, "unset") == 0)
906 char *opt = psql_scan_slash_option(scan_state,
907 OT_NORMAL, NULL, false);
911 psql_error("\\%s: missing required argument\n", cmd);
914 else if (!SetVariable(pset.vars, opt, NULL))
916 psql_error("\\%s: error\n", cmd);
922 /* \w -- write query buffer to file */
923 else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
926 bool is_pipe = false;
931 psql_error("no query buffer\n");
932 status = PSQL_CMD_ERROR;
936 fname = psql_scan_slash_option(scan_state,
937 OT_FILEPIPE, NULL, true);
938 expand_tilde(&fname);
942 psql_error("\\%s: missing required argument\n", cmd);
950 fd = popen(&fname[1], "w");
954 canonicalize_path(fname);
955 fd = fopen(fname, "w");
959 psql_error("%s: %s\n", fname, strerror(errno));
969 if (query_buf && query_buf->len > 0)
970 fprintf(fd, "%s\n", query_buf->data);
979 psql_error("%s: %s\n", fname, strerror(errno));
987 /* \x -- toggle expanded table representation */
988 else if (strcmp(cmd, "x") == 0)
990 char *opt = psql_scan_slash_option(scan_state,
991 OT_NORMAL, NULL, true);
993 success = do_pset("expanded", opt, &pset.popt, pset.quiet);
997 /* \z -- list table rights (equivalent to \dp) */
998 else if (strcmp(cmd, "z") == 0)
1000 char *pattern = psql_scan_slash_option(scan_state,
1001 OT_NORMAL, NULL, true);
1003 success = permissionsList(pattern);
1008 /* \! -- shell escape */
1009 else if (strcmp(cmd, "!") == 0)
1011 char *opt = psql_scan_slash_option(scan_state,
1012 OT_WHOLE_LINE, NULL, false);
1014 success = do_shell(opt);
1018 /* \? -- slash command help */
1019 else if (strcmp(cmd, "?") == 0)
1020 slashUsage(pset.popt.topt.pager);
1025 * These commands don't do anything. I just use them to test the parser.
1027 else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
1032 while ((value = psql_scan_slash_option(scan_state,
1033 OT_NORMAL, NULL, true)))
1035 fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value);
1042 status = PSQL_CMD_UNKNOWN;
1045 status = PSQL_CMD_ERROR;
1051 * Ask the user for a password; 'username' is the username the
1052 * password is for, if one has been explicitly specified. Returns a
1056 prompt_for_password(const char *username)
1060 if (username == NULL)
1061 result = simple_prompt("Password: ", 100, false);
1066 prompt_text = malloc(strlen(username) + 100);
1067 snprintf(prompt_text, strlen(username) + 100,
1068 _("Password for user %s: "), username);
1069 result = simple_prompt(prompt_text, 100, false);
1077 param_is_newly_set(const char *old_val, const char *new_val)
1079 if (new_val == NULL)
1082 if (old_val == NULL || strcmp(old_val, new_val) != 0)
1089 * do_connect -- handler for \connect
1091 * Connects to a database with given parameters. If there exists an
1092 * established connection, NULL values will be replaced with the ones
1093 * in the current connection. Otherwise NULL will be passed for that
1094 * parameter to PQsetdbLogin(), so the libpq defaults will be used.
1096 * In interactive mode, if connection fails with the given parameters,
1097 * the old connection will be kept.
1100 do_connect(char *dbname, char *user, char *host, char *port)
1102 PGconn *o_conn = pset.db,
1104 char *password = NULL;
1107 dbname = PQdb(o_conn);
1109 user = PQuser(o_conn);
1111 host = PQhost(o_conn);
1113 port = PQport(o_conn);
1116 * If the user asked to be prompted for a password, ask for one now. If
1117 * not, use the password from the old connection, provided the username
1118 * has not changed. Otherwise, try to connect without a password first,
1119 * and then ask for a password if needed.
1121 * XXX: this behavior leads to spurious connection attempts recorded in
1122 * the postmaster's log. But libpq offers no API that would let us obtain
1123 * a password and then continue with the first connection attempt.
1125 if (pset.getPassword)
1127 password = prompt_for_password(user);
1129 else if (o_conn && user && strcmp(PQuser(o_conn), user) == 0)
1131 password = strdup(PQpass(o_conn));
1136 n_conn = PQsetdbLogin(host, port, NULL, NULL,
1137 dbname, user, password);
1139 /* We can immediately discard the password -- no longer needed */
1143 if (PQstatus(n_conn) == CONNECTION_OK)
1147 * Connection attempt failed; either retry the connection attempt with
1148 * a new password, or give up.
1150 if (!password && PQconnectionNeedsPassword(n_conn))
1153 password = prompt_for_password(user);
1158 * Failed to connect to the database. In interactive mode, keep the
1159 * previous connection to the DB; in scripting mode, close our
1160 * previous connection as well.
1162 if (pset.cur_cmd_interactive)
1164 psql_error("%s", PQerrorMessage(n_conn));
1166 /* pset.db is left unmodified */
1168 fputs(_("Previous connection kept\n"), stderr);
1172 psql_error("\\connect: %s", PQerrorMessage(n_conn));
1185 * Replace the old connection with the new one, and update
1186 * connection-dependent variables.
1188 PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
1192 /* Tell the user about the new connection */
1195 printf(_("You are now connected to database \"%s\""), PQdb(pset.db));
1197 if (param_is_newly_set(PQhost(o_conn), PQhost(pset.db)))
1198 printf(_(" on host \"%s\""), PQhost(pset.db));
1200 if (param_is_newly_set(PQport(o_conn), PQport(pset.db)))
1201 printf(_(" at port \"%s\""), PQport(pset.db));
1203 if (param_is_newly_set(PQuser(o_conn), PQuser(pset.db)))
1204 printf(_(" as user \"%s\""), PQuser(pset.db));
1218 * Make psql's internal variables agree with connection state upon
1219 * establishing a new connection.
1224 /* get stuff from connection */
1225 pset.encoding = PQclientEncoding(pset.db);
1226 pset.popt.topt.encoding = pset.encoding;
1227 pset.sversion = PQserverVersion(pset.db);
1229 SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
1230 SetVariable(pset.vars, "USER", PQuser(pset.db));
1231 SetVariable(pset.vars, "HOST", PQhost(pset.db));
1232 SetVariable(pset.vars, "PORT", PQport(pset.db));
1233 SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
1235 /* send stuff to it, too */
1236 PQsetErrorVerbosity(pset.db, pset.verbosity);
1242 * Clear variables that should be not be set when there is no connection.
1245 UnsyncVariables(void)
1247 SetVariable(pset.vars, "DBNAME", NULL);
1248 SetVariable(pset.vars, "USER", NULL);
1249 SetVariable(pset.vars, "HOST", NULL);
1250 SetVariable(pset.vars, "PORT", NULL);
1251 SetVariable(pset.vars, "ENCODING", NULL);
1256 * do_edit -- handler for \e
1258 * If you do not specify a filename, the current query buffer will be copied
1259 * into a temporary one.
1263 editFile(const char *fname)
1265 const char *editorName;
1271 /* Find an editor to use */
1272 editorName = getenv("PSQL_EDITOR");
1274 editorName = getenv("EDITOR");
1276 editorName = getenv("VISUAL");
1278 editorName = DEFAULT_EDITOR;
1281 * On Unix the EDITOR value should *not* be quoted, since it might include
1282 * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
1283 * if necessary. But this policy is not very workable on Windows, due to
1284 * severe brain damage in their command shell plus the fact that standard
1285 * program paths include spaces.
1287 sys = pg_malloc(strlen(editorName) + strlen(fname) + 10 + 1);
1289 sprintf(sys, "exec %s '%s'", editorName, fname);
1291 sprintf(sys, "%s\"%s\" \"%s\"%s",
1292 SYSTEMQUOTE, editorName, fname, SYSTEMQUOTE);
1294 result = system(sys);
1296 psql_error("could not start editor \"%s\"\n", editorName);
1297 else if (result == 127)
1298 psql_error("could not start /bin/sh\n");
1307 do_edit(const char *filename_arg, PQExpBuffer query_buf)
1309 char fnametmp[MAXPGPATH];
1310 FILE *stream = NULL;
1319 fname = filename_arg;
1322 /* make a temp file to edit */
1324 const char *tmpdir = getenv("TMPDIR");
1329 char tmpdir[MAXPGPATH];
1332 ret = GetTempPath(MAXPGPATH, tmpdir);
1333 if (ret == 0 || ret > MAXPGPATH)
1335 psql_error("cannot locate temporary directory: %s",
1336 !ret ? strerror(errno) : "");
1341 * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
1342 * current directory to the supplied path unless we use only
1343 * backslashes, so we do that.
1347 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d", tmpdir,
1348 "/", (int) getpid());
1350 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d", tmpdir,
1351 "" /* trailing separator already present */ , (int) getpid());
1354 fname = (const char *) fnametmp;
1356 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
1358 stream = fdopen(fd, "w");
1360 if (fd == -1 || !stream)
1362 psql_error("could not open temporary file \"%s\": %s\n", fname, strerror(errno));
1367 unsigned int ql = query_buf->len;
1369 if (ql == 0 || query_buf->data[ql - 1] != '\n')
1371 appendPQExpBufferChar(query_buf, '\n');
1375 if (fwrite(query_buf->data, 1, ql, stream) != ql)
1377 psql_error("%s: %s\n", fname, strerror(errno));
1382 else if (fclose(stream) != 0)
1384 psql_error("%s: %s\n", fname, strerror(errno));
1391 if (!error && stat(fname, &before) != 0)
1393 psql_error("%s: %s\n", fname, strerror(errno));
1399 error = !editFile(fname);
1401 if (!error && stat(fname, &after) != 0)
1403 psql_error("%s: %s\n", fname, strerror(errno));
1407 if (!error && before.st_mtime != after.st_mtime)
1409 stream = fopen(fname, PG_BINARY_R);
1412 psql_error("%s: %s\n", fname, strerror(errno));
1417 /* read file back into query_buf */
1420 resetPQExpBuffer(query_buf);
1421 while (fgets(line, sizeof(line), stream) != NULL)
1422 appendPQExpBufferStr(query_buf, line);
1426 psql_error("%s: %s\n", fname, strerror(errno));
1435 /* remove temp file */
1438 if (remove(fname) == -1)
1440 psql_error("%s: %s\n", fname, strerror(errno));
1453 * Read commands from filename and then them to the main processing loop
1454 * Handler for \i, but can be used for other things as well. Returns
1455 * MainLoop() error code.
1458 process_file(char *filename, bool single_txn)
1466 return EXIT_FAILURE;
1468 canonicalize_path(filename);
1469 fd = fopen(filename, PG_BINARY_R);
1473 psql_error("%s: %s\n", filename, strerror(errno));
1474 return EXIT_FAILURE;
1477 oldfilename = pset.inputfile;
1478 pset.inputfile = filename;
1481 res = PSQLexec("BEGIN", false);
1482 result = MainLoop(fd);
1484 res = PSQLexec("COMMIT", false);
1487 pset.inputfile = oldfilename;
1498 _align2string(enum printFormat in)
1505 case PRINT_UNALIGNED:
1520 case PRINT_TROFF_MS:
1529 do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
1536 vallen = strlen(value);
1539 if (strcmp(param, "format") == 0)
1543 else if (pg_strncasecmp("unaligned", value, vallen) == 0)
1544 popt->topt.format = PRINT_UNALIGNED;
1545 else if (pg_strncasecmp("aligned", value, vallen) == 0)
1546 popt->topt.format = PRINT_ALIGNED;
1547 else if (pg_strncasecmp("wrapped", value, vallen) == 0)
1548 popt->topt.format = PRINT_WRAPPED;
1549 else if (pg_strncasecmp("html", value, vallen) == 0)
1550 popt->topt.format = PRINT_HTML;
1551 else if (pg_strncasecmp("latex", value, vallen) == 0)
1552 popt->topt.format = PRINT_LATEX;
1553 else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
1554 popt->topt.format = PRINT_TROFF_MS;
1557 psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, latex, troff-ms\n");
1562 printf(_("Output format is %s.\n"), _align2string(popt->topt.format));
1565 /* set border style/width */
1566 else if (strcmp(param, "border") == 0)
1569 popt->topt.border = atoi(value);
1572 printf(_("Border style is %d.\n"), popt->topt.border);
1575 /* set expanded/vertical mode */
1576 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
1579 popt->topt.expanded = ParseVariableBool(value);
1581 popt->topt.expanded = !popt->topt.expanded;
1583 printf(popt->topt.expanded
1584 ? _("Expanded display is on.\n")
1585 : _("Expanded display is off.\n"));
1588 /* locale-aware numeric output */
1589 else if (strcmp(param, "numericlocale") == 0)
1592 popt->topt.numericLocale = ParseVariableBool(value);
1594 popt->topt.numericLocale = !popt->topt.numericLocale;
1597 if (popt->topt.numericLocale)
1598 puts(_("Showing locale-adjusted numeric output."));
1600 puts(_("Locale-adjusted numeric output is off."));
1605 else if (strcmp(param, "null") == 0)
1609 free(popt->nullPrint);
1610 popt->nullPrint = pg_strdup(value);
1613 printf(_("Null display is \"%s\".\n"), popt->nullPrint ? popt->nullPrint : "");
1616 /* field separator for unaligned text */
1617 else if (strcmp(param, "fieldsep") == 0)
1621 free(popt->topt.fieldSep);
1622 popt->topt.fieldSep = pg_strdup(value);
1625 printf(_("Field separator is \"%s\".\n"), popt->topt.fieldSep);
1628 /* record separator for unaligned text */
1629 else if (strcmp(param, "recordsep") == 0)
1633 free(popt->topt.recordSep);
1634 popt->topt.recordSep = pg_strdup(value);
1638 if (strcmp(popt->topt.recordSep, "\n") == 0)
1639 printf(_("Record separator is <newline>."));
1641 printf(_("Record separator is \"%s\".\n"), popt->topt.recordSep);
1645 /* toggle between full and tuples-only format */
1646 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
1649 popt->topt.tuples_only = ParseVariableBool(value);
1651 popt->topt.tuples_only = !popt->topt.tuples_only;
1654 if (popt->topt.tuples_only)
1655 puts(_("Showing only tuples."));
1657 puts(_("Tuples only is off."));
1661 /* set title override */
1662 else if (strcmp(param, "title") == 0)
1668 popt->title = pg_strdup(value);
1673 printf(_("Title is \"%s\".\n"), popt->title);
1675 printf(_("Title is unset.\n"));
1679 /* set HTML table tag options */
1680 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
1682 free(popt->topt.tableAttr);
1684 popt->topt.tableAttr = NULL;
1686 popt->topt.tableAttr = pg_strdup(value);
1690 if (popt->topt.tableAttr)
1691 printf(_("Table attribute is \"%s\".\n"), popt->topt.tableAttr);
1693 printf(_("Table attributes unset.\n"));
1697 /* toggle use of pager */
1698 else if (strcmp(param, "pager") == 0)
1700 if (value && pg_strcasecmp(value, "always") == 0)
1701 popt->topt.pager = 2;
1703 if (ParseVariableBool(value))
1704 popt->topt.pager = 1;
1706 popt->topt.pager = 0;
1707 else if (popt->topt.pager == 1)
1708 popt->topt.pager = 0;
1710 popt->topt.pager = 1;
1713 if (popt->topt.pager == 1)
1714 puts(_("Pager is used for long output."));
1715 else if (popt->topt.pager == 2)
1716 puts(_("Pager is always used."));
1718 puts(_("Pager usage is off."));
1722 /* disable "(x rows)" footer */
1723 else if (strcmp(param, "footer") == 0)
1726 popt->default_footer = ParseVariableBool(value);
1728 popt->default_footer = !popt->default_footer;
1731 if (popt->default_footer)
1732 puts(_("Default footer is on."));
1734 puts(_("Default footer is off."));
1738 /* set border style/width */
1739 else if (strcmp(param, "columns") == 0)
1742 popt->topt.columns = atoi(value);
1745 printf(_("Target width for \"wrapped\" format is %d.\n"), popt->topt.columns);
1750 psql_error("\\pset: unknown option: %s\n", param);
1760 #define DEFAULT_SHELL "/bin/sh"
1763 * CMD.EXE is in different places in different Win32 releases so we
1764 * have to rely on the path to find it.
1766 #define DEFAULT_SHELL "cmd.exe"
1770 do_shell(const char *command)
1777 const char *shellName;
1779 shellName = getenv("SHELL");
1781 if (shellName == NULL)
1782 shellName = getenv("COMSPEC");
1784 if (shellName == NULL)
1785 shellName = DEFAULT_SHELL;
1787 sys = pg_malloc(strlen(shellName) + 16);
1790 /* See EDITOR handling comment for an explaination */
1791 "exec %s", shellName);
1794 /* See EDITOR handling comment for an explaination */
1795 "%s\"%s\"%s", SYSTEMQUOTE, shellName, SYSTEMQUOTE);
1797 result = system(sys);
1801 result = system(command);
1803 if (result == 127 || result == -1)
1805 psql_error("\\!: failed\n");