2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2003, PostgreSQL Global Development Group
6 * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.115 2004/03/27 18:01:40 momjian Exp $
8 #include "postgres_fe.h"
17 #include <sys/types.h> /* for umask() */
18 #include <sys/stat.h> /* for stat() */
19 #include <fcntl.h> /* open() flags */
20 #include <unistd.h> /* for geteuid(), getpid(), stat() */
29 #include "pqexpbuffer.h"
36 #include "large_obj.h"
41 #include "variables.h"
42 #include "mb/pg_wchar.h"
45 /* functions for use in this file */
46 static backslashResult exec_command(const char *cmd,
47 PsqlScanState scan_state,
48 PQExpBuffer query_buf);
49 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf);
50 static bool do_connect(const char *new_dbname, const char *new_user);
51 static bool do_shell(const char *command);
57 * Handles all the different commands that start with '\',
58 * ordinarily called by MainLoop().
60 * scan_state is a lexer working state that is set to continue scanning
61 * just after the '\'. The lexer is advanced past the command and all
62 * arguments on return.
64 * 'query_buf' contains the query-so-far, which may be modified by
65 * execution of the backslash command (for example, \r clears it).
66 * query_buf can be NULL if there is no query so far.
68 * Returns a status code indicating what action is desired, see command.h.
73 HandleSlashCmds(PsqlScanState scan_state,
74 PQExpBuffer query_buf)
76 backslashResult status = CMD_SKIP_LINE;
80 psql_assert(scan_state);
82 /* Parse off the command name */
83 cmd = psql_scan_slash_command(scan_state);
85 /* And try to execute it */
86 status = exec_command(cmd, scan_state, query_buf);
88 if (status == CMD_UNKNOWN && strlen(cmd) > 1)
91 * If the command was not recognized, try to parse it as a
92 * one-letter command with immediately following argument (a
93 * still-supported, but no longer encouraged, syntax).
97 /* don't change cmd until we know it's okay */
101 psql_scan_slash_pushback(scan_state, cmd + 1);
103 status = exec_command(new_cmd, scan_state, query_buf);
105 if (status != CMD_UNKNOWN)
107 /* adjust cmd for possible messages below */
110 #if 0 /* turned out to be too annoying */
111 if (isalpha((unsigned char) cmd[0]))
112 psql_error("Warning: This syntax is deprecated.\n");
117 if (status == CMD_UNKNOWN)
119 if (pset.cur_cmd_interactive)
120 fprintf(stderr, gettext("Invalid command \\%s. Try \\? for help.\n"), cmd);
122 psql_error("invalid command \\%s\n", cmd);
126 /* eat the rest of the options, if any */
127 while ((arg = psql_scan_slash_option(scan_state,
128 OT_NORMAL, NULL, false)))
130 if (status != CMD_ERROR)
131 psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
135 /* if there is a trailing \\, swallow it */
136 psql_scan_slash_command_end(scan_state);
144 * Subroutine to actually try to execute a backslash command.
146 static backslashResult
147 exec_command(const char *cmd,
148 PsqlScanState scan_state,
149 PQExpBuffer query_buf)
151 bool success = true; /* indicate here if the command ran ok or
153 bool quiet = QUIET();
154 backslashResult status = CMD_SKIP_LINE;
157 * \a -- toggle field alignment This makes little sense but we keep it
160 if (strcmp(cmd, "a") == 0)
162 if (pset.popt.topt.format != PRINT_ALIGNED)
163 success = do_pset("format", "aligned", &pset.popt, quiet);
165 success = do_pset("format", "unaligned", &pset.popt, quiet);
168 /* \C -- override table title (formerly change HTML caption) */
169 else if (strcmp(cmd, "C") == 0)
171 char *opt = psql_scan_slash_option(scan_state,
172 OT_NORMAL, NULL, true);
174 success = do_pset("title", opt, &pset.popt, quiet);
179 * \c or \connect -- connect to new database or as different user
181 * \c foo bar connect to db "foo" as user "bar"
182 * \c foo [-] connect to db "foo" as current user
183 * \c - bar connect to current db as user "bar"
184 * \c connect to default db as default user
187 else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
195 * Ideally we should treat the arguments as SQL identifiers. But
196 * for backwards compatibility with 7.2 and older pg_dump files,
197 * we have to take unquoted arguments verbatim (don't downcase
198 * them). For now, double-quoted arguments may be stripped of
199 * double quotes (as if SQL identifiers). By 7.4 or so, pg_dump
200 * files can be expected to double-quote all mixed-case \connect
201 * arguments, and then we can get rid of OT_SQLIDHACK.
203 opt1 = psql_scan_slash_option(scan_state,
204 OT_SQLIDHACK, &opt1q, true);
205 opt2 = psql_scan_slash_option(scan_state,
206 OT_SQLIDHACK, &opt2q, true);
210 success = do_connect(!opt1q && (strcmp(opt1, "-") == 0 || strcmp(opt1, "") == 0) ? "" : opt1,
211 !opt2q && (strcmp(opt2, "-") == 0 || strcmp(opt2, "") == 0) ? "" : opt2);
213 /* gave database name */
214 success = do_connect(!opt1q && (strcmp(opt1, "-") == 0 || strcmp(opt1, "") == 0) ? "" : opt1, "");
216 /* connect to default db as default user */
217 success = do_connect(NULL, NULL);
224 else if (strcmp(cmd, "cd") == 0)
226 char *opt = psql_scan_slash_option(scan_state,
227 OT_NORMAL, NULL, true);
237 pw = getpwuid(geteuid());
240 psql_error("could not get home directory: %s\n", strerror(errno));
247 * On Windows, 'cd' without arguments prints the current
248 * directory, so if someone wants to code this here instead...
254 if (chdir(dir) == -1)
256 psql_error("\\%s: could not change directory to \"%s\": %s\n",
257 cmd, dir, strerror(errno));
266 else if (strcasecmp(cmd, "copy") == 0)
268 char *opt = psql_scan_slash_option(scan_state,
269 OT_WHOLE_LINE, NULL, false);
271 success = do_copy(opt);
276 else if (strcmp(cmd, "copyright") == 0)
280 else if (cmd[0] == 'd')
285 /* We don't do SQLID reduction on the pattern yet */
286 pattern = psql_scan_slash_option(scan_state,
287 OT_NORMAL, NULL, true);
289 show_verbose = strchr(cmd, '+') ? true : false;
296 success = describeTableDetails(pattern, show_verbose);
298 /* standard listing of interesting things */
299 success = listTables("tvs", NULL, show_verbose);
302 success = describeAggregates(pattern, show_verbose);
305 success = listConversions(pattern);
308 success = listCasts(pattern);
311 success = objectDescription(pattern);
314 success = listDomains(pattern);
317 success = describeFunctions(pattern, show_verbose);
320 success = describeGroups(pattern);
323 success = do_lo_list();
326 success = listSchemas(pattern);
329 success = describeOperators(pattern);
332 success = permissionsList(pattern);
335 success = describeTypes(pattern, show_verbose);
342 success = listTables(&cmd[1], pattern, show_verbose);
345 success = describeUsers(pattern);
349 status = CMD_UNKNOWN;
358 * \e or \edit -- edit the current query buffer (or a file and make it
361 else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
367 psql_error("no query buffer\n");
372 fname = psql_scan_slash_option(scan_state,
373 OT_NORMAL, NULL, true);
374 expand_tilde(&fname);
375 status = do_edit(fname, query_buf) ? CMD_NEWEDIT : CMD_ERROR;
380 /* \echo and \qecho */
381 else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
385 bool no_newline = false;
389 if (strcmp(cmd, "qecho") == 0)
390 fout = pset.queryFout;
394 while ((value = psql_scan_slash_option(scan_state,
395 OT_NORMAL, "ed, false)))
397 if (!quoted && strcmp(value, "-n") == 0)
413 /* \encoding -- set/show client side encoding */
414 else if (strcmp(cmd, "encoding") == 0)
416 char *encoding = psql_scan_slash_option(scan_state,
417 OT_NORMAL, NULL, false);
422 puts(pg_encoding_to_char(pset.encoding));
427 if (PQsetClientEncoding(pset.db, encoding) == -1)
428 psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
431 /* save encoding info into psql internal data */
432 pset.encoding = PQclientEncoding(pset.db);
433 pset.popt.topt.encoding = pset.encoding;
434 SetVariable(pset.vars, "ENCODING",
435 pg_encoding_to_char(pset.encoding));
441 /* \f -- change field separator */
442 else if (strcmp(cmd, "f") == 0)
444 char *fname = psql_scan_slash_option(scan_state,
445 OT_NORMAL, NULL, false);
447 success = do_pset("fieldsep", fname, &pset.popt, quiet);
451 /* \g means send query */
452 else if (strcmp(cmd, "g") == 0)
454 char *fname = psql_scan_slash_option(scan_state,
455 OT_FILEPIPE, NULL, false);
461 expand_tilde(&fname);
462 pset.gfname = pg_strdup(fname);
469 else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
471 char *opt = psql_scan_slash_option(scan_state,
472 OT_WHOLE_LINE, NULL, false);
474 helpSQL(opt, pset.popt.topt.pager);
479 else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
481 if (pset.popt.topt.format != PRINT_HTML)
482 success = do_pset("format", "html", &pset.popt, quiet);
484 success = do_pset("format", "aligned", &pset.popt, quiet);
488 /* \i is include file */
489 else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
491 char *fname = psql_scan_slash_option(scan_state,
492 OT_NORMAL, NULL, true);
496 psql_error("\\%s: missing required argument\n", cmd);
501 expand_tilde(&fname);
502 success = (process_file(fname) == EXIT_SUCCESS);
507 /* \l is list databases */
508 else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0)
509 success = listAllDbs(false);
510 else if (strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
511 success = listAllDbs(true);
514 * large object things
516 else if (strncmp(cmd, "lo_", 3) == 0)
521 opt1 = psql_scan_slash_option(scan_state,
522 OT_NORMAL, NULL, true);
523 opt2 = psql_scan_slash_option(scan_state,
524 OT_NORMAL, NULL, true);
526 if (strcmp(cmd + 3, "export") == 0)
530 psql_error("\\%s: missing required argument\n", cmd);
536 success = do_lo_export(opt1, opt2);
540 else if (strcmp(cmd + 3, "import") == 0)
544 psql_error("\\%s: missing required argument\n", cmd);
550 success = do_lo_import(opt1, opt2);
554 else if (strcmp(cmd + 3, "list") == 0)
555 success = do_lo_list();
557 else if (strcmp(cmd + 3, "unlink") == 0)
561 psql_error("\\%s: missing required argument\n", cmd);
565 success = do_lo_unlink(opt1);
569 status = CMD_UNKNOWN;
576 /* \o -- set query output */
577 else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
579 char *fname = psql_scan_slash_option(scan_state,
580 OT_FILEPIPE, NULL, true);
582 expand_tilde(&fname);
583 success = setQFout(fname);
587 /* \p prints the current query buffer */
588 else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
590 if (query_buf && query_buf->len > 0)
591 puts(query_buf->data);
593 puts(gettext("Query buffer is empty."));
597 /* \pset -- set printing parameters */
598 else if (strcmp(cmd, "pset") == 0)
600 char *opt0 = psql_scan_slash_option(scan_state,
601 OT_NORMAL, NULL, false);
602 char *opt1 = psql_scan_slash_option(scan_state,
603 OT_NORMAL, NULL, false);
607 psql_error("\\%s: missing required argument\n", cmd);
611 success = do_pset(opt0, opt1, &pset.popt, quiet);
618 else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
619 status = CMD_TERMINATE;
621 /* reset(clear) the buffer */
622 else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
624 resetPQExpBuffer(query_buf);
625 psql_scan_reset(scan_state);
627 puts(gettext("Query buffer reset (cleared)."));
630 /* \s save history in a file or show it on the screen */
631 else if (strcmp(cmd, "s") == 0)
633 char *fname = psql_scan_slash_option(scan_state,
634 OT_NORMAL, NULL, true);
636 expand_tilde(&fname);
637 /* This scrolls off the screen when using /dev/tty */
638 success = saveHistory(fname ? fname : "/dev/tty");
640 if (success && !quiet && fname)
641 printf(gettext("Wrote history to file \"%s\".\n"), fname);
645 /* \set -- generalized set variable/option command */
646 else if (strcmp(cmd, "set") == 0)
648 char *opt0 = psql_scan_slash_option(scan_state,
649 OT_NORMAL, NULL, false);
653 /* list all variables */
654 PrintVariables(pset.vars);
660 * Set variable to the concatenation of the arguments.
665 opt = psql_scan_slash_option(scan_state,
666 OT_NORMAL, NULL, false);
667 newval = pg_strdup(opt ? opt : "");
670 while ((opt = psql_scan_slash_option(scan_state,
671 OT_NORMAL, NULL, false)))
673 newval = realloc(newval, strlen(newval) + strlen(opt) + 1);
676 psql_error("out of memory\n");
683 if (SetVariable(pset.vars, opt0, newval))
685 /* Check for special variables */
686 if (strcmp(opt0, "VERBOSITY") == 0)
687 SyncVerbosityVariable();
691 psql_error("\\%s: error\n", cmd);
699 /* \t -- turn off headers and row count */
700 else if (strcmp(cmd, "t") == 0)
701 success = do_pset("tuples_only", NULL, &pset.popt, quiet);
704 /* \T -- define html <table ...> attributes */
705 else if (strcmp(cmd, "T") == 0)
707 char *value = psql_scan_slash_option(scan_state,
708 OT_NORMAL, NULL, false);
710 success = do_pset("tableattr", value, &pset.popt, quiet);
714 /* \timing -- toggle timing of queries */
715 else if (strcmp(cmd, "timing") == 0)
717 pset.timing = !pset.timing;
721 puts(gettext("Timing is on."));
723 puts(gettext("Timing is off."));
728 else if (strcmp(cmd, "unset") == 0)
730 char *opt = psql_scan_slash_option(scan_state,
731 OT_NORMAL, NULL, false);
735 psql_error("\\%s: missing required argument\n", cmd);
738 else if (!SetVariable(pset.vars, opt, NULL))
740 psql_error("\\%s: error\n", cmd);
746 /* \w -- write query buffer to file */
747 else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
750 bool is_pipe = false;
755 psql_error("no query buffer\n");
760 fname = psql_scan_slash_option(scan_state,
761 OT_FILEPIPE, NULL, true);
762 expand_tilde(&fname);
766 psql_error("\\%s: missing required argument\n", cmd);
774 fd = popen(&fname[1], "w");
777 fd = fopen(fname, "w");
781 psql_error("%s: %s\n", fname, strerror(errno));
791 if (query_buf && query_buf->len > 0)
792 fprintf(fd, "%s\n", query_buf->data);
801 psql_error("%s: %s\n", fname, strerror(errno));
809 /* \x -- toggle expanded table representation */
810 else if (strcmp(cmd, "x") == 0)
811 success = do_pset("expanded", NULL, &pset.popt, quiet);
814 /* \z -- list table rights (equivalent to \dp) */
815 else if (strcmp(cmd, "z") == 0)
817 char *pattern = psql_scan_slash_option(scan_state,
818 OT_NORMAL, NULL, true);
820 success = permissionsList(pattern);
825 /* \! -- shell escape */
826 else if (strcmp(cmd, "!") == 0)
828 char *opt = psql_scan_slash_option(scan_state,
829 OT_WHOLE_LINE, NULL, false);
831 success = do_shell(opt);
835 /* \? -- slash command help */
836 else if (strcmp(cmd, "?") == 0)
837 slashUsage(pset.popt.topt.pager);
842 * These commands don't do anything. I just use them to test the
845 else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
850 while ((value = psql_scan_slash_option(scan_state,
851 OT_NORMAL, NULL, true)))
853 fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value);
860 status = CMD_UNKNOWN;
871 * -- handler for \connect
873 * Connects to a database (new_dbname) as a certain user (new_user).
874 * The new user can be NULL. A db name of "-" is the same as the old one.
875 * (That is, the one currently in pset. But pset.db can also be NULL. A NULL
876 * dbname is handled by libpq.)
877 * Returns true if all ok, false if the new connection couldn't be established.
878 * The old connection will be kept if the session is interactive.
881 do_connect(const char *new_dbname, const char *new_user)
883 PGconn *oldconn = pset.db;
884 const char *dbparam = NULL;
885 const char *userparam = NULL;
886 const char *pwparam = NULL;
887 char *prompted_password = NULL;
889 bool success = false;
891 /* Delete variables (in case we fail before setting them anew) */
894 /* If dbname is "" then use old name, else new one (even if NULL) */
895 if (oldconn && new_dbname && PQdb(oldconn) && strcmp(new_dbname, "") == 0)
896 dbparam = PQdb(oldconn);
898 dbparam = new_dbname;
900 /* If user is "" then use the old one */
901 if (new_user && PQuser(oldconn) && strcmp(new_user, "") == 0)
902 userparam = PQuser(oldconn);
904 userparam = new_user;
906 /* need to prompt for password? */
907 if (pset.getPassword)
908 pwparam = prompted_password = simple_prompt("Password: ", 100, false);
911 * Use old password (if any) if no new one given and we are
912 * reconnecting as same user
914 if (!pwparam && oldconn && PQuser(oldconn) && userparam &&
915 strcmp(PQuser(oldconn), userparam) == 0)
916 pwparam = PQpass(oldconn);
921 pset.db = PQsetdbLogin(PQhost(oldconn), PQport(oldconn),
922 NULL, NULL, dbparam, userparam, pwparam);
924 if (PQstatus(pset.db) == CONNECTION_BAD &&
925 strcmp(PQerrorMessage(pset.db), "fe_sendauth: no password supplied\n") == 0 &&
930 free(prompted_password);
931 prompted_password = NULL;
932 pwparam = prompted_password = simple_prompt("Password: ", 100, false);
936 free(prompted_password);
939 * If connection failed, try at least keep the old one. That's
940 * probably more convenient than just kicking you out of the program.
942 if (!pset.db || PQstatus(pset.db) == CONNECTION_BAD)
944 if (pset.cur_cmd_interactive)
946 psql_error("%s", PQerrorMessage(pset.db));
950 fputs(gettext("Previous connection kept\n"), stderr);
959 * we don't want unpredictable things to happen in scripting
962 psql_error("\\connect: %s", PQerrorMessage(pset.db));
973 if (userparam != new_user) /* no new user */
974 printf(gettext("You are now connected to database \"%s\".\n"), dbparam);
975 else if (dbparam != new_dbname) /* no new db */
976 printf(gettext("You are now connected as new user \"%s\".\n"), new_user);
979 printf(gettext("You are now connected to database \"%s\" as user \"%s\".\n"),
980 PQdb(pset.db), PQuser(pset.db));
989 PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);
991 /* Update variables */
1001 * Make psql's internal variables agree with connection state upon
1002 * establishing a new connection.
1007 /* get stuff from connection */
1008 pset.encoding = PQclientEncoding(pset.db);
1009 pset.popt.topt.encoding = pset.encoding;
1011 SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
1012 SetVariable(pset.vars, "USER", PQuser(pset.db));
1013 SetVariable(pset.vars, "HOST", PQhost(pset.db));
1014 SetVariable(pset.vars, "PORT", PQport(pset.db));
1015 SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
1017 /* send stuff to it, too */
1018 SyncVerbosityVariable();
1024 * Clear variables that should be not be set when there is no connection.
1027 UnsyncVariables(void)
1029 SetVariable(pset.vars, "DBNAME", NULL);
1030 SetVariable(pset.vars, "USER", NULL);
1031 SetVariable(pset.vars, "HOST", NULL);
1032 SetVariable(pset.vars, "PORT", NULL);
1033 SetVariable(pset.vars, "ENCODING", NULL);
1037 * Update connection state from VERBOSITY variable
1040 SyncVerbosityVariable(void)
1042 switch (SwitchVariable(pset.vars, "VERBOSITY",
1043 "default", "terse", "verbose", NULL))
1045 case 1: /* default */
1046 pset.verbosity = PQERRORS_DEFAULT;
1049 pset.verbosity = PQERRORS_TERSE;
1051 case 3: /* verbose */
1052 pset.verbosity = PQERRORS_VERBOSE;
1054 default: /* not set or unrecognized value */
1055 pset.verbosity = PQERRORS_DEFAULT;
1059 PQsetErrorVerbosity(pset.db, pset.verbosity);
1064 * do_edit -- handler for \e
1066 * If you do not specify a filename, the current query buffer will be copied
1067 * into a temporary one.
1071 editFile(const char *fname)
1073 const char *editorName;
1079 /* Find an editor to use */
1080 editorName = getenv("PSQL_EDITOR");
1082 editorName = getenv("EDITOR");
1084 editorName = getenv("VISUAL");
1086 editorName = DEFAULT_EDITOR;
1088 sys = pg_malloc(strlen(editorName) + strlen(fname) + 10 + 1);
1093 "%s '%s'", editorName, fname);
1094 result = system(sys);
1096 psql_error("could not start editor \"%s\"\n", editorName);
1097 else if (result == 127)
1098 psql_error("could not start /bin/sh\n");
1107 do_edit(const char *filename_arg, PQExpBuffer query_buf)
1109 char fnametmp[MAXPGPATH];
1110 FILE *stream = NULL;
1121 fname = filename_arg;
1125 /* make a temp file to edit */
1127 const char *tmpdirenv = getenv("TMPDIR");
1129 snprintf(fnametmp, sizeof(fnametmp), "%s/psql.edit.%ld.%ld",
1130 tmpdirenv ? tmpdirenv : "/tmp",
1131 (long) geteuid(), (long) getpid());
1133 GetTempFileName(".", "psql", 0, fnametmp);
1135 fname = (const char *) fnametmp;
1137 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
1139 stream = fdopen(fd, "w");
1141 if (fd == -1 || !stream)
1143 psql_error("could not open temporary file \"%s\": %s\n", fname, strerror(errno));
1148 unsigned int ql = query_buf->len;
1150 if (ql == 0 || query_buf->data[ql - 1] != '\n')
1152 appendPQExpBufferChar(query_buf, '\n');
1156 if (fwrite(query_buf->data, 1, ql, stream) != ql)
1158 psql_error("%s: %s\n", fname, strerror(errno));
1163 else if (fclose(stream) != 0)
1165 psql_error("%s: %s\n", fname, strerror(errno));
1173 if (!error && stat(fname, &before) != 0)
1175 psql_error("%s: %s\n", fname, strerror(errno));
1182 error = !editFile(fname);
1185 if (!error && stat(fname, &after) != 0)
1187 psql_error("%s: %s\n", fname, strerror(errno));
1191 if (!error && before.st_mtime != after.st_mtime)
1197 stream = fopen(fname, "r");
1200 psql_error("%s: %s\n", fname, strerror(errno));
1205 /* read file back in */
1208 resetPQExpBuffer(query_buf);
1209 while (fgets(line, sizeof(line), stream) != NULL)
1210 appendPQExpBufferStr(query_buf, line);
1214 psql_error("%s: %s\n", fname, strerror(errno));
1219 #ifdef HAVE_REPLACE_HISTORY_ENTRY
1221 replace_history_entry(where_history(), query_buf->data, NULL);
1223 add_history(query_buf->data);
1231 /* remove temp file */
1234 if (remove(fname) == -1)
1236 psql_error("%s: %s\n", fname, strerror(errno));
1249 * Read commands from filename and then them to the main processing loop
1250 * Handler for \i, but can be used for other things as well.
1253 process_file(char *filename)
1262 fd = fopen(filename, "r");
1266 psql_error("%s: %s\n", filename, strerror(errno));
1270 oldfilename = pset.inputfile;
1271 pset.inputfile = filename;
1272 result = MainLoop(fd);
1274 pset.inputfile = oldfilename;
1285 _align2string(enum printFormat in)
1292 case PRINT_UNALIGNED:
1310 do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
1317 vallen = strlen(value);
1320 if (strcmp(param, "format") == 0)
1324 else if (strncasecmp("unaligned", value, vallen) == 0)
1325 popt->topt.format = PRINT_UNALIGNED;
1326 else if (strncasecmp("aligned", value, vallen) == 0)
1327 popt->topt.format = PRINT_ALIGNED;
1328 else if (strncasecmp("html", value, vallen) == 0)
1329 popt->topt.format = PRINT_HTML;
1330 else if (strncasecmp("latex", value, vallen) == 0)
1331 popt->topt.format = PRINT_LATEX;
1334 psql_error("\\pset: allowed formats are unaligned, aligned, html, latex\n");
1339 printf(gettext("Output format is %s.\n"), _align2string(popt->topt.format));
1342 /* set border style/width */
1343 else if (strcmp(param, "border") == 0)
1346 popt->topt.border = atoi(value);
1349 printf(gettext("Border style is %d.\n"), popt->topt.border);
1352 /* set expanded/vertical mode */
1353 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
1355 popt->topt.expanded = !popt->topt.expanded;
1357 printf(popt->topt.expanded
1358 ? gettext("Expanded display is on.\n")
1359 : gettext("Expanded display is off.\n"));
1363 else if (strcmp(param, "null") == 0)
1367 free(popt->nullPrint);
1368 popt->nullPrint = pg_strdup(value);
1371 printf(gettext("Null display is \"%s\".\n"), popt->nullPrint ? popt->nullPrint : "");
1374 /* field separator for unaligned text */
1375 else if (strcmp(param, "fieldsep") == 0)
1379 free(popt->topt.fieldSep);
1380 popt->topt.fieldSep = pg_strdup(value);
1383 printf(gettext("Field separator is \"%s\".\n"), popt->topt.fieldSep);
1386 /* record separator for unaligned text */
1387 else if (strcmp(param, "recordsep") == 0)
1391 free(popt->topt.recordSep);
1392 popt->topt.recordSep = pg_strdup(value);
1396 if (strcmp(popt->topt.recordSep, "\n") == 0)
1397 printf(gettext("Record separator is <newline>."));
1399 printf(gettext("Record separator is \"%s\".\n"), popt->topt.recordSep);
1403 /* toggle between full and barebones format */
1404 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
1406 popt->topt.tuples_only = !popt->topt.tuples_only;
1409 if (popt->topt.tuples_only)
1410 puts(gettext("Showing only tuples."));
1412 puts(gettext("Tuples only is off."));
1416 /* set title override */
1417 else if (strcmp(param, "title") == 0)
1423 popt->title = pg_strdup(value);
1428 printf(gettext("Title is \"%s\".\n"), popt->title);
1430 printf(gettext("Title is unset.\n"));
1434 /* set HTML table tag options */
1435 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
1437 free(popt->topt.tableAttr);
1439 popt->topt.tableAttr = NULL;
1441 popt->topt.tableAttr = pg_strdup(value);
1445 if (popt->topt.tableAttr)
1446 printf(gettext("Table attribute is \"%s\".\n"), popt->topt.tableAttr);
1448 printf(gettext("Table attributes unset.\n"));
1452 /* toggle use of pager */
1453 else if (strcmp(param, "pager") == 0)
1455 if (value && strcasecmp(value, "always") == 0)
1456 popt->topt.pager = 2;
1457 else if (popt->topt.pager == 1)
1458 popt->topt.pager = 0;
1460 popt->topt.pager = 1;
1463 if (popt->topt.pager == 1)
1464 puts(gettext("Pager is used for long output."));
1465 else if (popt->topt.pager == 2)
1466 puts(gettext("Pager is always used."));
1468 puts(gettext("Pager usage is off."));
1472 /* disable "(x rows)" footer */
1473 else if (strcmp(param, "footer") == 0)
1475 popt->default_footer = !popt->default_footer;
1478 if (popt->default_footer)
1479 puts(gettext("Default footer is on."));
1481 puts(gettext("Default footer is off."));
1487 psql_error("\\pset: unknown option: %s\n", param);
1496 #define DEFAULT_SHELL "/bin/sh"
1499 do_shell(const char *command)
1506 const char *shellName;
1508 shellName = getenv("SHELL");
1509 if (shellName == NULL)
1510 shellName = DEFAULT_SHELL;
1512 sys = pg_malloc(strlen(shellName) + 16);
1518 result = system(sys);
1522 result = system(command);
1524 if (result == 127 || result == -1)
1526 psql_error("\\!: failed\n");