2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2013, PostgreSQL Global Development Group
6 * src/bin/psql/command.c
8 #include "postgres_fe.h"
11 #ifdef __BORLANDC__ /* needed for BCC */
21 #include <sys/types.h> /* for umask() */
22 #include <sys/stat.h> /* for stat() */
23 #include <fcntl.h> /* open() flags */
24 #include <unistd.h> /* for geteuid(), getpid(), stat() */
30 #include <sys/types.h> /* for umask() */
31 #include <sys/stat.h> /* for stat() */
34 #include <openssl/ssl.h>
37 #include "portability/instr_time.h"
40 #include "pqexpbuffer.h"
41 #include "dumputils.h"
48 #include "large_obj.h"
53 #include "variables.h"
56 /* functions for use in this file */
57 static backslashResult exec_command(const char *cmd,
58 PsqlScanState scan_state,
59 PQExpBuffer query_buf);
60 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
61 int lineno, bool *edited);
62 static bool do_connect(char *dbname, char *user, char *host, char *port);
63 static bool do_shell(const char *command);
64 static bool do_watch(PQExpBuffer query_buf, long sleep);
65 static bool lookup_function_oid(PGconn *conn, const char *desc, Oid *foid);
66 static bool get_create_function_cmd(PGconn *conn, Oid oid, PQExpBuffer buf);
67 static int strip_lineno_from_funcdesc(char *func);
68 static void minimal_error_message(PGresult *res);
70 static void printSSLInfo(void);
71 static bool printPsetInfo(const char *param, struct printQueryOpt *popt);
74 static void checkWin32Codepage(void);
82 * Handles all the different commands that start with '\'.
83 * Ordinarily called by MainLoop().
85 * scan_state is a lexer working state that is set to continue scanning
86 * just after the '\'. The lexer is advanced past the command and all
87 * arguments on return.
89 * 'query_buf' contains the query-so-far, which may be modified by
90 * execution of the backslash command (for example, \r clears it).
91 * query_buf can be NULL if there is no query so far.
93 * Returns a status code indicating what action is desired, see command.h.
98 HandleSlashCmds(PsqlScanState scan_state,
99 PQExpBuffer query_buf)
101 backslashResult status = PSQL_CMD_SKIP_LINE;
105 Assert(scan_state != NULL);
107 /* Parse off the command name */
108 cmd = psql_scan_slash_command(scan_state);
110 /* And try to execute it */
111 status = exec_command(cmd, scan_state, query_buf);
113 if (status == PSQL_CMD_UNKNOWN)
115 if (pset.cur_cmd_interactive)
116 psql_error("Invalid command \\%s. Try \\? for help.\n", cmd);
118 psql_error("invalid command \\%s\n", cmd);
119 status = PSQL_CMD_ERROR;
122 if (status != PSQL_CMD_ERROR)
124 /* eat any remaining arguments after a valid command */
125 /* note we suppress evaluation of backticks here */
126 while ((arg = psql_scan_slash_option(scan_state,
127 OT_NO_EVAL, NULL, false)))
129 psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
135 /* silently throw away rest of line after an erroneous command */
136 while ((arg = psql_scan_slash_option(scan_state,
137 OT_WHOLE_LINE, NULL, false)))
141 /* if there is a trailing \\, swallow it */
142 psql_scan_slash_command_end(scan_state);
146 /* some commands write to queryFout, so make sure output is sent */
147 fflush(pset.queryFout);
153 * Read and interpret an argument to the \connect slash command.
156 read_connect_arg(PsqlScanState scan_state)
162 * Ideally we should treat the arguments as SQL identifiers. But for
163 * backwards compatibility with 7.2 and older pg_dump files, we have to
164 * take unquoted arguments verbatim (don't downcase them). For now,
165 * double-quoted arguments may be stripped of double quotes (as if SQL
166 * identifiers). By 7.4 or so, pg_dump files can be expected to
167 * double-quote all mixed-case \connect arguments, and then we can get rid
170 result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, "e, true);
178 if (*result == '\0' || strcmp(result, "-") == 0)
186 * Subroutine to actually try to execute a backslash command.
188 static backslashResult
189 exec_command(const char *cmd,
190 PsqlScanState scan_state,
191 PQExpBuffer query_buf)
193 bool success = true; /* indicate here if the command ran ok or
195 backslashResult status = PSQL_CMD_SKIP_LINE;
198 * \a -- toggle field alignment This makes little sense but we keep it
201 if (strcmp(cmd, "a") == 0)
203 if (pset.popt.topt.format != PRINT_ALIGNED)
204 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
206 success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
209 /* \C -- override table title (formerly change HTML caption) */
210 else if (strcmp(cmd, "C") == 0)
212 char *opt = psql_scan_slash_option(scan_state,
213 OT_NORMAL, NULL, true);
215 success = do_pset("title", opt, &pset.popt, pset.quiet);
220 * \c or \connect -- connect to database using the specified parameters.
222 * \c dbname user host port
224 * If any of these parameters are omitted or specified as '-', the current
225 * value of the parameter will be used instead. If the parameter has no
226 * current value, the default value for that parameter will be used. Some
229 * \c - - hst Connect to current database on current port of host
230 * "hst" as current user. \c - usr - prt Connect to current database on
231 * "prt" port of current host as user "usr". \c dbs Connect to
232 * "dbs" database on current port of current host as current user.
234 else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
241 opt1 = read_connect_arg(scan_state);
242 opt2 = read_connect_arg(scan_state);
243 opt3 = read_connect_arg(scan_state);
244 opt4 = read_connect_arg(scan_state);
246 success = do_connect(opt1, opt2, opt3, opt4);
255 else if (strcmp(cmd, "cd") == 0)
257 char *opt = psql_scan_slash_option(scan_state,
258 OT_NORMAL, NULL, true);
268 pw = getpwuid(geteuid());
271 psql_error("could not get home directory: %s\n", strerror(errno));
278 * On Windows, 'cd' without arguments prints the current
279 * directory, so if someone wants to code this here instead...
285 if (chdir(dir) == -1)
287 psql_error("\\%s: could not change directory to \"%s\": %s\n",
288 cmd, dir, strerror(errno));
294 pset.dirname = pg_strdup(dir);
295 canonicalize_path(pset.dirname);
301 /* \conninfo -- display information about the current connection */
302 else if (strcmp(cmd, "conninfo") == 0)
304 char *db = PQdb(pset.db);
305 char *host = PQhost(pset.db);
308 printf(_("You are currently not connected to a database.\n"));
312 host = DEFAULT_PGSOCKET_DIR;
313 /* If the host is an absolute path, the connection is via socket */
314 if (is_absolute_path(host))
315 printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
316 db, PQuser(pset.db), host, PQport(pset.db));
318 printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
319 db, PQuser(pset.db), host, PQport(pset.db));
325 else if (pg_strcasecmp(cmd, "copy") == 0)
327 char *opt = psql_scan_slash_option(scan_state,
328 OT_WHOLE_LINE, NULL, false);
330 success = do_copy(opt);
335 else if (strcmp(cmd, "copyright") == 0)
339 else if (cmd[0] == 'd')
345 /* We don't do SQLID reduction on the pattern yet */
346 pattern = psql_scan_slash_option(scan_state,
347 OT_NORMAL, NULL, true);
349 show_verbose = strchr(cmd, '+') ? true : false;
350 show_system = strchr(cmd, 'S') ? true : false;
358 success = describeTableDetails(pattern, show_verbose, show_system);
360 /* standard listing of interesting things */
361 success = listTables("tvmsE", NULL, show_verbose, show_system);
364 success = describeAggregates(pattern, show_verbose, show_system);
367 success = describeTablespaces(pattern, show_verbose);
370 success = listConversions(pattern, show_verbose, show_system);
373 success = listCasts(pattern, show_verbose);
376 if (strncmp(cmd, "ddp", 3) == 0)
377 success = listDefaultACLs(pattern);
379 success = objectDescription(pattern, show_system);
382 success = listDomains(pattern, show_verbose, show_system);
384 case 'f': /* function subsystem */
394 success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
397 status = PSQL_CMD_UNKNOWN;
402 /* no longer distinct from \du */
403 success = describeRoles(pattern, show_verbose);
406 success = do_lo_list();
409 success = listLanguages(pattern, show_verbose, show_system);
412 success = listSchemas(pattern, show_verbose, show_system);
415 success = describeOperators(pattern, show_system);
418 success = listCollations(pattern, show_verbose, show_system);
421 success = permissionsList(pattern);
424 success = describeTypes(pattern, show_verbose, show_system);
432 success = listTables(&cmd[1], pattern, show_verbose, show_system);
435 if (cmd[2] == 'd' && cmd[3] == 's')
437 char *pattern2 = NULL;
440 pattern2 = psql_scan_slash_option(scan_state,
441 OT_NORMAL, NULL, true);
442 success = listDbRoleSettings(pattern, pattern2);
445 success = PSQL_CMD_UNKNOWN;
448 success = describeRoles(pattern, show_verbose);
450 case 'F': /* text search subsystem */
455 success = listTSConfigs(pattern, show_verbose);
458 success = listTSParsers(pattern, show_verbose);
461 success = listTSDictionaries(pattern, show_verbose);
464 success = listTSTemplates(pattern, show_verbose);
467 status = PSQL_CMD_UNKNOWN;
471 case 'e': /* SQL/MED subsystem */
475 success = listForeignServers(pattern, show_verbose);
478 success = listUserMappings(pattern, show_verbose);
481 success = listForeignDataWrappers(pattern, show_verbose);
484 success = listForeignTables(pattern, show_verbose);
487 status = PSQL_CMD_UNKNOWN;
491 case 'x': /* Extensions */
493 success = listExtensionContents(pattern);
495 success = listExtensions(pattern);
497 case 'y': /* Event Triggers */
498 success = listEventTriggers(pattern, show_verbose);
501 status = PSQL_CMD_UNKNOWN;
510 * \e or \edit -- edit the current query buffer, or edit a file and make
511 * it the query buffer
513 else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
517 psql_error("no query buffer\n");
518 status = PSQL_CMD_ERROR;
526 fname = psql_scan_slash_option(scan_state,
527 OT_NORMAL, NULL, true);
530 /* try to get separate lineno arg */
531 ln = psql_scan_slash_option(scan_state,
532 OT_NORMAL, NULL, true);
535 /* only one arg; maybe it is lineno not fname */
537 strspn(fname, "0123456789") == strlen(fname))
539 /* all digits, so assume it is lineno */
550 psql_error("invalid line number: %s\n", ln);
551 status = PSQL_CMD_ERROR;
554 if (status != PSQL_CMD_ERROR)
556 expand_tilde(&fname);
558 canonicalize_path(fname);
559 if (do_edit(fname, query_buf, lineno, NULL))
560 status = PSQL_CMD_NEWEDIT;
562 status = PSQL_CMD_ERROR;
572 * \ef -- edit the named function, or present a blank CREATE FUNCTION
573 * template if no argument is given
575 else if (strcmp(cmd, "ef") == 0)
579 if (pset.sversion < 80400)
581 psql_error("The server (version %d.%d) does not support editing function source.\n",
582 pset.sversion / 10000, (pset.sversion / 100) % 100);
583 status = PSQL_CMD_ERROR;
587 psql_error("no query buffer\n");
588 status = PSQL_CMD_ERROR;
593 Oid foid = InvalidOid;
595 func = psql_scan_slash_option(scan_state,
596 OT_WHOLE_LINE, NULL, true);
597 lineno = strip_lineno_from_funcdesc(func);
600 /* error already reported */
601 status = PSQL_CMD_ERROR;
605 /* set up an empty command to fill in */
606 printfPQExpBuffer(query_buf,
607 "CREATE FUNCTION ( )\n"
610 " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
614 else if (!lookup_function_oid(pset.db, func, &foid))
616 /* error already reported */
617 status = PSQL_CMD_ERROR;
619 else if (!get_create_function_cmd(pset.db, foid, query_buf))
621 /* error already reported */
622 status = PSQL_CMD_ERROR;
627 * lineno "1" should correspond to the first line of the
628 * function body. We expect that pg_get_functiondef() will
629 * emit that on a line beginning with "AS ", and that there
630 * can be no such line before the real start of the function
631 * body. Increment lineno by the number of lines before that
632 * line, so that it becomes relative to the first line of the
633 * function definition.
635 const char *lines = query_buf->data;
637 while (*lines != '\0')
639 if (strncmp(lines, "AS ", 3) == 0)
642 /* find start of next line */
643 lines = strchr(lines, '\n');
654 if (status != PSQL_CMD_ERROR)
658 if (!do_edit(NULL, query_buf, lineno, &edited))
659 status = PSQL_CMD_ERROR;
661 puts(_("No changes"));
663 status = PSQL_CMD_NEWEDIT;
667 /* \echo and \qecho */
668 else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
672 bool no_newline = false;
676 if (strcmp(cmd, "qecho") == 0)
677 fout = pset.queryFout;
681 while ((value = psql_scan_slash_option(scan_state,
682 OT_NORMAL, "ed, false)))
684 if (!quoted && strcmp(value, "-n") == 0)
700 /* \encoding -- set/show client side encoding */
701 else if (strcmp(cmd, "encoding") == 0)
703 char *encoding = psql_scan_slash_option(scan_state,
704 OT_NORMAL, NULL, false);
709 puts(pg_encoding_to_char(pset.encoding));
714 if (PQsetClientEncoding(pset.db, encoding) == -1)
715 psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
718 /* save encoding info into psql internal data */
719 pset.encoding = PQclientEncoding(pset.db);
720 pset.popt.topt.encoding = pset.encoding;
721 SetVariable(pset.vars, "ENCODING",
722 pg_encoding_to_char(pset.encoding));
728 /* \f -- change field separator */
729 else if (strcmp(cmd, "f") == 0)
731 char *fname = psql_scan_slash_option(scan_state,
732 OT_NORMAL, NULL, false);
734 success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
738 /* \g [filename] -- send query, optionally with output to file/pipe */
739 else if (strcmp(cmd, "g") == 0)
741 char *fname = psql_scan_slash_option(scan_state,
742 OT_FILEPIPE, NULL, false);
748 expand_tilde(&fname);
749 pset.gfname = pg_strdup(fname);
752 status = PSQL_CMD_SEND;
755 /* \gset [prefix] -- send query and store result into variables */
756 else if (strcmp(cmd, "gset") == 0)
758 char *prefix = psql_scan_slash_option(scan_state,
759 OT_NORMAL, NULL, false);
762 pset.gset_prefix = prefix;
765 /* we must set a non-NULL prefix to trigger storing */
766 pset.gset_prefix = pg_strdup("");
768 status = PSQL_CMD_SEND;
772 else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
774 char *opt = psql_scan_slash_option(scan_state,
775 OT_WHOLE_LINE, NULL, false);
778 /* strip any trailing spaces and semicolons */
783 (isspace((unsigned char) opt[len - 1])
784 || opt[len - 1] == ';'))
788 helpSQL(opt, pset.popt.topt.pager);
793 else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
795 if (pset.popt.topt.format != PRINT_HTML)
796 success = do_pset("format", "html", &pset.popt, pset.quiet);
798 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
802 /* \i and \ir include files */
803 else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0
804 || strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
806 char *fname = psql_scan_slash_option(scan_state,
807 OT_NORMAL, NULL, true);
811 psql_error("\\%s: missing required argument\n", cmd);
816 bool include_relative;
818 include_relative = (strcmp(cmd, "ir") == 0
819 || strcmp(cmd, "include_relative") == 0);
820 expand_tilde(&fname);
821 success = (process_file(fname, false, include_relative) == EXIT_SUCCESS);
826 /* \l is list databases */
827 else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
828 strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
833 pattern = psql_scan_slash_option(scan_state,
834 OT_NORMAL, NULL, true);
836 show_verbose = strchr(cmd, '+') ? true : false;
838 success = listAllDbs(pattern, show_verbose);
845 * large object things
847 else if (strncmp(cmd, "lo_", 3) == 0)
852 opt1 = psql_scan_slash_option(scan_state,
853 OT_NORMAL, NULL, true);
854 opt2 = psql_scan_slash_option(scan_state,
855 OT_NORMAL, NULL, true);
857 if (strcmp(cmd + 3, "export") == 0)
861 psql_error("\\%s: missing required argument\n", cmd);
867 success = do_lo_export(opt1, opt2);
871 else if (strcmp(cmd + 3, "import") == 0)
875 psql_error("\\%s: missing required argument\n", cmd);
881 success = do_lo_import(opt1, opt2);
885 else if (strcmp(cmd + 3, "list") == 0)
886 success = do_lo_list();
888 else if (strcmp(cmd + 3, "unlink") == 0)
892 psql_error("\\%s: missing required argument\n", cmd);
896 success = do_lo_unlink(opt1);
900 status = PSQL_CMD_UNKNOWN;
907 /* \o -- set query output */
908 else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
910 char *fname = psql_scan_slash_option(scan_state,
911 OT_FILEPIPE, NULL, true);
913 expand_tilde(&fname);
914 success = setQFout(fname);
918 /* \p prints the current query buffer */
919 else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
921 if (query_buf && query_buf->len > 0)
922 puts(query_buf->data);
923 else if (!pset.quiet)
924 puts(_("Query buffer is empty."));
928 /* \password -- set user password */
929 else if (strcmp(cmd, "password") == 0)
934 pw1 = simple_prompt("Enter new password: ", 100, false);
935 pw2 = simple_prompt("Enter it again: ", 100, false);
937 if (strcmp(pw1, pw2) != 0)
939 psql_error("Passwords didn't match.\n");
944 char *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true);
946 char *encrypted_password;
951 user = PQuser(pset.db);
953 encrypted_password = PQencryptPassword(pw1, user);
955 if (!encrypted_password)
957 psql_error("Password encryption failed.\n");
965 initPQExpBuffer(&buf);
966 printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
968 appendStringLiteralConn(&buf, encrypted_password, pset.db);
969 res = PSQLexec(buf.data, false);
970 termPQExpBuffer(&buf);
975 PQfreemem(encrypted_password);
986 /* \prompt -- prompt and set variable */
987 else if (strcmp(cmd, "prompt") == 0)
994 arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
995 arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
999 psql_error("\\%s: missing required argument\n", cmd);
1014 if (!pset.inputfile)
1015 result = simple_prompt(prompt_text, 4096, true);
1020 fputs(prompt_text, stdout);
1023 result = gets_fromFile(stdin);
1026 if (!SetVariable(pset.vars, opt, result))
1028 psql_error("\\%s: error while setting variable\n", cmd);
1039 /* \pset -- set printing parameters */
1040 else if (strcmp(cmd, "pset") == 0)
1042 char *opt0 = psql_scan_slash_option(scan_state,
1043 OT_NORMAL, NULL, false);
1044 char *opt1 = psql_scan_slash_option(scan_state,
1045 OT_NORMAL, NULL, false);
1050 /* list all variables */
1051 static const char *const my_list[] = {
1052 "border", "columns", "expanded", "fieldsep",
1053 "footer", "format", "linestyle", "null",
1054 "numericlocale", "pager", "recordsep",
1055 "tableattr", "title", "tuples_only",
1057 for (i = 0; my_list[i] != NULL; i++) {
1058 printPsetInfo(my_list[i], &pset.popt);
1065 success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
1072 else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
1073 status = PSQL_CMD_TERMINATE;
1075 /* reset(clear) the buffer */
1076 else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
1078 resetPQExpBuffer(query_buf);
1079 psql_scan_reset(scan_state);
1081 puts(_("Query buffer reset (cleared)."));
1084 /* \s save history in a file or show it on the screen */
1085 else if (strcmp(cmd, "s") == 0)
1087 char *fname = psql_scan_slash_option(scan_state,
1088 OT_NORMAL, NULL, true);
1090 #if defined(WIN32) && !defined(__CYGWIN__)
1093 * XXX This does not work for all terminal environments or for output
1094 * containing non-ASCII characters; see comments in simple_prompt().
1096 #define DEVTTY "con"
1098 #define DEVTTY "/dev/tty"
1101 expand_tilde(&fname);
1102 /* This scrolls off the screen when using /dev/tty */
1103 success = saveHistory(fname ? fname : DEVTTY, -1, false, false);
1104 if (success && !pset.quiet && fname)
1105 printf(gettext("Wrote history to file \"%s/%s\".\n"),
1106 pset.dirname ? pset.dirname : ".", fname);
1112 /* \set -- generalized set variable/option command */
1113 else if (strcmp(cmd, "set") == 0)
1115 char *opt0 = psql_scan_slash_option(scan_state,
1116 OT_NORMAL, NULL, false);
1120 /* list all variables */
1121 PrintVariables(pset.vars);
1127 * Set variable to the concatenation of the arguments.
1132 opt = psql_scan_slash_option(scan_state,
1133 OT_NORMAL, NULL, false);
1134 newval = pg_strdup(opt ? opt : "");
1137 while ((opt = psql_scan_slash_option(scan_state,
1138 OT_NORMAL, NULL, false)))
1140 newval = realloc(newval, strlen(newval) + strlen(opt) + 1);
1143 psql_error("out of memory\n");
1146 strcat(newval, opt);
1150 if (!SetVariable(pset.vars, opt0, newval))
1152 psql_error("\\%s: error while setting variable\n", cmd);
1161 /* \setenv -- set environment command */
1162 else if (strcmp(cmd, "setenv") == 0)
1164 char *envvar = psql_scan_slash_option(scan_state,
1165 OT_NORMAL, NULL, false);
1166 char *envval = psql_scan_slash_option(scan_state,
1167 OT_NORMAL, NULL, false);
1171 psql_error("\\%s: missing required argument\n", cmd);
1174 else if (strchr(envvar, '=') != NULL)
1176 psql_error("\\%s: environment variable name must not contain \"=\"\n",
1182 /* No argument - unset the environment variable */
1188 /* Set variable to the value of the next argument */
1191 newval = psprintf("%s=%s", envvar, envval);
1196 * Do not free newval here, it will screw up the environment if
1197 * you do. See putenv man page for details. That means we leak a
1198 * bit of memory here, but not enough to worry about.
1205 /* \sf -- show a function's source code */
1206 else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
1208 bool show_linenumbers = (strcmp(cmd, "sf+") == 0);
1209 PQExpBuffer func_buf;
1211 Oid foid = InvalidOid;
1213 func_buf = createPQExpBuffer();
1214 func = psql_scan_slash_option(scan_state,
1215 OT_WHOLE_LINE, NULL, true);
1216 if (pset.sversion < 80400)
1218 psql_error("The server (version %d.%d) does not support showing function source.\n",
1219 pset.sversion / 10000, (pset.sversion / 100) % 100);
1220 status = PSQL_CMD_ERROR;
1224 psql_error("function name is required\n");
1225 status = PSQL_CMD_ERROR;
1227 else if (!lookup_function_oid(pset.db, func, &foid))
1229 /* error already reported */
1230 status = PSQL_CMD_ERROR;
1232 else if (!get_create_function_cmd(pset.db, foid, func_buf))
1234 /* error already reported */
1235 status = PSQL_CMD_ERROR;
1242 /* Select output stream: stdout, pager, or file */
1243 if (pset.queryFout == stdout)
1245 /* count lines in function to see if pager is needed */
1247 const char *lines = func_buf->data;
1249 while (*lines != '\0')
1252 /* find start of next line */
1253 lines = strchr(lines, '\n');
1259 output = PageOutput(lineno, pset.popt.topt.pager);
1264 /* use previously set output file, without pager */
1265 output = pset.queryFout;
1269 if (show_linenumbers)
1271 bool in_header = true;
1273 char *lines = func_buf->data;
1276 * lineno "1" should correspond to the first line of the
1277 * function body. We expect that pg_get_functiondef() will
1278 * emit that on a line beginning with "AS ", and that there
1279 * can be no such line before the real start of the function
1282 * Note that this loop scribbles on func_buf.
1284 while (*lines != '\0')
1288 if (in_header && strncmp(lines, "AS ", 3) == 0)
1290 /* increment lineno only for body's lines */
1294 /* find and mark end of current line */
1295 eol = strchr(lines, '\n');
1299 /* show current line as appropriate */
1301 fprintf(output, " %s\n", lines);
1303 fprintf(output, "%-7d %s\n", lineno, lines);
1305 /* advance to next line, if any */
1313 /* just send the function definition to output */
1314 fputs(func_buf->data, output);
1323 destroyPQExpBuffer(func_buf);
1326 /* \t -- turn off headers and row count */
1327 else if (strcmp(cmd, "t") == 0)
1329 char *opt = psql_scan_slash_option(scan_state,
1330 OT_NORMAL, NULL, true);
1332 success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
1336 /* \T -- define html <table ...> attributes */
1337 else if (strcmp(cmd, "T") == 0)
1339 char *value = psql_scan_slash_option(scan_state,
1340 OT_NORMAL, NULL, false);
1342 success = do_pset("tableattr", value, &pset.popt, pset.quiet);
1346 /* \timing -- toggle timing of queries */
1347 else if (strcmp(cmd, "timing") == 0)
1349 char *opt = psql_scan_slash_option(scan_state,
1350 OT_NORMAL, NULL, false);
1353 pset.timing = ParseVariableBool(opt);
1355 pset.timing = !pset.timing;
1359 puts(_("Timing is on."));
1361 puts(_("Timing is off."));
1367 else if (strcmp(cmd, "unset") == 0)
1369 char *opt = psql_scan_slash_option(scan_state,
1370 OT_NORMAL, NULL, false);
1374 psql_error("\\%s: missing required argument\n", cmd);
1377 else if (!SetVariable(pset.vars, opt, NULL))
1379 psql_error("\\%s: error while setting variable\n", cmd);
1385 /* \w -- write query buffer to file */
1386 else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
1389 bool is_pipe = false;
1394 psql_error("no query buffer\n");
1395 status = PSQL_CMD_ERROR;
1399 fname = psql_scan_slash_option(scan_state,
1400 OT_FILEPIPE, NULL, true);
1401 expand_tilde(&fname);
1405 psql_error("\\%s: missing required argument\n", cmd);
1410 if (fname[0] == '|')
1413 fd = popen(&fname[1], "w");
1417 canonicalize_path(fname);
1418 fd = fopen(fname, "w");
1422 psql_error("%s: %s\n", fname, strerror(errno));
1432 if (query_buf && query_buf->len > 0)
1433 fprintf(fd, "%s\n", query_buf->data);
1436 result = pclose(fd);
1438 result = fclose(fd);
1442 psql_error("%s: %s\n", fname, strerror(errno));
1450 /* \watch -- execute a query every N seconds */
1451 else if (strcmp(cmd, "watch") == 0)
1453 char *opt = psql_scan_slash_option(scan_state,
1454 OT_NORMAL, NULL, true);
1457 /* Convert optional sleep-length argument */
1460 sleep = strtol(opt, NULL, 10);
1466 success = do_watch(query_buf, sleep);
1468 /* Reset the query buffer as though for \r */
1469 resetPQExpBuffer(query_buf);
1470 psql_scan_reset(scan_state);
1473 /* \x -- set or toggle expanded table representation */
1474 else if (strcmp(cmd, "x") == 0)
1476 char *opt = psql_scan_slash_option(scan_state,
1477 OT_NORMAL, NULL, true);
1479 success = do_pset("expanded", opt, &pset.popt, pset.quiet);
1483 /* \z -- list table rights (equivalent to \dp) */
1484 else if (strcmp(cmd, "z") == 0)
1486 char *pattern = psql_scan_slash_option(scan_state,
1487 OT_NORMAL, NULL, true);
1489 success = permissionsList(pattern);
1494 /* \! -- shell escape */
1495 else if (strcmp(cmd, "!") == 0)
1497 char *opt = psql_scan_slash_option(scan_state,
1498 OT_WHOLE_LINE, NULL, false);
1500 success = do_shell(opt);
1504 /* \? -- slash command help */
1505 else if (strcmp(cmd, "?") == 0)
1506 slashUsage(pset.popt.topt.pager);
1511 * These commands don't do anything. I just use them to test the parser.
1513 else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
1518 while ((value = psql_scan_slash_option(scan_state,
1519 OT_NORMAL, NULL, true)))
1521 psql_error("+ opt(%d) = |%s|\n", i++, value);
1528 status = PSQL_CMD_UNKNOWN;
1531 status = PSQL_CMD_ERROR;
1537 * Ask the user for a password; 'username' is the username the
1538 * password is for, if one has been explicitly specified. Returns a
1542 prompt_for_password(const char *username)
1546 if (username == NULL)
1547 result = simple_prompt("Password: ", 100, false);
1552 prompt_text = psprintf(_("Password for user %s: "), username);
1553 result = simple_prompt(prompt_text, 100, false);
1561 param_is_newly_set(const char *old_val, const char *new_val)
1563 if (new_val == NULL)
1566 if (old_val == NULL || strcmp(old_val, new_val) != 0)
1573 * do_connect -- handler for \connect
1575 * Connects to a database with given parameters. If there exists an
1576 * established connection, NULL values will be replaced with the ones
1577 * in the current connection. Otherwise NULL will be passed for that
1578 * parameter to PQconnectdbParams(), so the libpq defaults will be used.
1580 * In interactive mode, if connection fails with the given parameters,
1581 * the old connection will be kept.
1584 do_connect(char *dbname, char *user, char *host, char *port)
1586 PGconn *o_conn = pset.db,
1588 char *password = NULL;
1590 if (!o_conn && (!dbname || !user || !host || !port))
1593 * We don't know the supplied connection parameters and don't want to
1594 * connect to the wrong database by using defaults, so require all
1595 * parameters to be specified.
1597 psql_error("All connection parameters must be supplied because no "
1598 "database connection exists\n");
1603 dbname = PQdb(o_conn);
1605 user = PQuser(o_conn);
1607 host = PQhost(o_conn);
1609 port = PQport(o_conn);
1612 * If the user asked to be prompted for a password, ask for one now. If
1613 * not, use the password from the old connection, provided the username
1614 * has not changed. Otherwise, try to connect without a password first,
1615 * and then ask for a password if needed.
1617 * XXX: this behavior leads to spurious connection attempts recorded in
1618 * the postmaster's log. But libpq offers no API that would let us obtain
1619 * a password and then continue with the first connection attempt.
1621 if (pset.getPassword == TRI_YES)
1623 password = prompt_for_password(user);
1625 else if (o_conn && user && strcmp(PQuser(o_conn), user) == 0)
1627 password = pg_strdup(PQpass(o_conn));
1632 #define PARAMS_ARRAY_SIZE 8
1633 const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
1634 const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
1636 keywords[0] = "host";
1638 keywords[1] = "port";
1640 keywords[2] = "user";
1642 keywords[3] = "password";
1643 values[3] = password;
1644 keywords[4] = "dbname";
1646 keywords[5] = "fallback_application_name";
1647 values[5] = pset.progname;
1648 keywords[6] = "client_encoding";
1649 values[6] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto";
1653 n_conn = PQconnectdbParams(keywords, values, true);
1658 /* We can immediately discard the password -- no longer needed */
1662 if (PQstatus(n_conn) == CONNECTION_OK)
1666 * Connection attempt failed; either retry the connection attempt with
1667 * a new password, or give up.
1669 if (!password && PQconnectionNeedsPassword(n_conn) && pset.getPassword != TRI_NO)
1672 password = prompt_for_password(user);
1677 * Failed to connect to the database. In interactive mode, keep the
1678 * previous connection to the DB; in scripting mode, close our
1679 * previous connection as well.
1681 if (pset.cur_cmd_interactive)
1683 psql_error("%s", PQerrorMessage(n_conn));
1685 /* pset.db is left unmodified */
1687 psql_error("Previous connection kept\n");
1691 psql_error("\\connect: %s", PQerrorMessage(n_conn));
1704 * Replace the old connection with the new one, and update
1705 * connection-dependent variables.
1707 PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
1710 connection_warnings(false); /* Must be after SyncVariables */
1712 /* Tell the user about the new connection */
1715 if (param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) ||
1716 param_is_newly_set(PQport(o_conn), PQport(pset.db)))
1718 char *host = PQhost(pset.db);
1721 host = DEFAULT_PGSOCKET_DIR;
1722 /* If the host is an absolute path, the connection is via socket */
1723 if (is_absolute_path(host))
1724 printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
1725 PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
1727 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
1728 PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
1731 printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
1732 PQdb(pset.db), PQuser(pset.db));
1742 connection_warnings(bool in_startup)
1744 if (!pset.quiet && !pset.notty)
1746 int client_ver = PG_VERSION_NUM;
1748 if (pset.sversion != client_ver)
1750 const char *server_version;
1751 char server_ver_str[16];
1753 /* Try to get full text form, might include "devel" etc */
1754 server_version = PQparameterStatus(pset.db, "server_version");
1755 if (!server_version)
1757 snprintf(server_ver_str, sizeof(server_ver_str),
1759 pset.sversion / 10000,
1760 (pset.sversion / 100) % 100,
1761 pset.sversion % 100);
1762 server_version = server_ver_str;
1765 printf(_("%s (%s, server %s)\n"),
1766 pset.progname, PG_VERSION, server_version);
1768 /* For version match, only print psql banner on startup. */
1769 else if (in_startup)
1770 printf("%s (%s)\n", pset.progname, PG_VERSION);
1772 if (pset.sversion / 100 > client_ver / 100)
1773 printf(_("WARNING: %s major version %d.%d, server major version %d.%d.\n"
1774 " Some psql features might not work.\n"),
1775 pset.progname, client_ver / 10000, (client_ver / 100) % 100,
1776 pset.sversion / 10000, (pset.sversion / 100) % 100);
1779 checkWin32Codepage();
1789 * Prints information about the current SSL connection, if SSL is in use
1798 ssl = PQgetssl(pset.db);
1800 return; /* no SSL */
1802 SSL_get_cipher_bits(ssl, &sslbits);
1803 printf(_("SSL connection (cipher: %s, bits: %d)\n"),
1804 SSL_get_cipher(ssl), sslbits);
1808 * If psql is compiled without SSL but is using a libpq with SSL, we
1809 * cannot figure out the specifics about the connection. But we know it's
1812 if (PQgetssl(pset.db))
1813 printf(_("SSL connection (unknown cipher)\n"));
1819 * checkWin32Codepage
1821 * Prints a warning when win32 console codepage differs from Windows codepage
1825 checkWin32Codepage(void)
1831 concp = GetConsoleCP();
1834 printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
1835 " 8-bit characters might not work correctly. See psql reference\n"
1836 " page \"Notes for Windows users\" for details.\n"),
1846 * Make psql's internal variables agree with connection state upon
1847 * establishing a new connection.
1852 /* get stuff from connection */
1853 pset.encoding = PQclientEncoding(pset.db);
1854 pset.popt.topt.encoding = pset.encoding;
1855 pset.sversion = PQserverVersion(pset.db);
1857 SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
1858 SetVariable(pset.vars, "USER", PQuser(pset.db));
1859 SetVariable(pset.vars, "HOST", PQhost(pset.db));
1860 SetVariable(pset.vars, "PORT", PQport(pset.db));
1861 SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
1863 /* send stuff to it, too */
1864 PQsetErrorVerbosity(pset.db, pset.verbosity);
1870 * Clear variables that should be not be set when there is no connection.
1873 UnsyncVariables(void)
1875 SetVariable(pset.vars, "DBNAME", NULL);
1876 SetVariable(pset.vars, "USER", NULL);
1877 SetVariable(pset.vars, "HOST", NULL);
1878 SetVariable(pset.vars, "PORT", NULL);
1879 SetVariable(pset.vars, "ENCODING", NULL);
1884 * do_edit -- handler for \e
1886 * If you do not specify a filename, the current query buffer will be copied
1887 * into a temporary one.
1890 editFile(const char *fname, int lineno)
1892 const char *editorName;
1893 const char *editor_lineno_arg = NULL;
1897 Assert(fname != NULL);
1899 /* Find an editor to use */
1900 editorName = getenv("PSQL_EDITOR");
1902 editorName = getenv("EDITOR");
1904 editorName = getenv("VISUAL");
1906 editorName = DEFAULT_EDITOR;
1908 /* Get line number argument, if we need it. */
1911 editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
1912 #ifdef DEFAULT_EDITOR_LINENUMBER_ARG
1913 if (!editor_lineno_arg)
1914 editor_lineno_arg = DEFAULT_EDITOR_LINENUMBER_ARG;
1916 if (!editor_lineno_arg)
1918 psql_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n");
1924 * On Unix the EDITOR value should *not* be quoted, since it might include
1925 * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
1926 * if necessary. But this policy is not very workable on Windows, due to
1927 * severe brain damage in their command shell plus the fact that standard
1928 * program paths include spaces.
1932 sys = psprintf("exec %s %s%d '%s'",
1933 editorName, editor_lineno_arg, lineno, fname);
1935 sys = psprintf("exec %s '%s'",
1939 sys = psprintf(SYSTEMQUOTE "\"%s\" %s%d \"%s\"" SYSTEMQUOTE,
1940 editorName, editor_lineno_arg, lineno, fname);
1942 sys = psprintf(SYSTEMQUOTE "\"%s\" \"%s\"" SYSTEMQUOTE,
1945 result = system(sys);
1947 psql_error("could not start editor \"%s\"\n", editorName);
1948 else if (result == 127)
1949 psql_error("could not start /bin/sh\n");
1958 do_edit(const char *filename_arg, PQExpBuffer query_buf,
1959 int lineno, bool *edited)
1961 char fnametmp[MAXPGPATH];
1962 FILE *stream = NULL;
1971 fname = filename_arg;
1974 /* make a temp file to edit */
1976 const char *tmpdir = getenv("TMPDIR");
1981 char tmpdir[MAXPGPATH];
1984 ret = GetTempPath(MAXPGPATH, tmpdir);
1985 if (ret == 0 || ret > MAXPGPATH)
1987 psql_error("could not locate temporary directory: %s\n",
1988 !ret ? strerror(errno) : "");
1993 * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
1994 * current directory to the supplied path unless we use only
1995 * backslashes, so we do that.
1999 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
2000 "/", (int) getpid());
2002 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
2003 "" /* trailing separator already present */ , (int) getpid());
2006 fname = (const char *) fnametmp;
2008 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
2010 stream = fdopen(fd, "w");
2012 if (fd == -1 || !stream)
2014 psql_error("could not open temporary file \"%s\": %s\n", fname, strerror(errno));
2019 unsigned int ql = query_buf->len;
2021 if (ql == 0 || query_buf->data[ql - 1] != '\n')
2023 appendPQExpBufferChar(query_buf, '\n');
2027 if (fwrite(query_buf->data, 1, ql, stream) != ql)
2029 psql_error("%s: %s\n", fname, strerror(errno));
2034 else if (fclose(stream) != 0)
2036 psql_error("%s: %s\n", fname, strerror(errno));
2043 if (!error && stat(fname, &before) != 0)
2045 psql_error("%s: %s\n", fname, strerror(errno));
2051 error = !editFile(fname, lineno);
2053 if (!error && stat(fname, &after) != 0)
2055 psql_error("%s: %s\n", fname, strerror(errno));
2059 if (!error && before.st_mtime != after.st_mtime)
2061 stream = fopen(fname, PG_BINARY_R);
2064 psql_error("%s: %s\n", fname, strerror(errno));
2069 /* read file back into query_buf */
2072 resetPQExpBuffer(query_buf);
2073 while (fgets(line, sizeof(line), stream) != NULL)
2074 appendPQExpBufferStr(query_buf, line);
2078 psql_error("%s: %s\n", fname, strerror(errno));
2090 /* remove temp file */
2093 if (remove(fname) == -1)
2095 psql_error("%s: %s\n", fname, strerror(errno));
2108 * Reads commands from filename and passes them to the main processing loop.
2109 * Handler for \i and \ir, but can be used for other things as well. Returns
2110 * MainLoop() error code.
2112 * If use_relative_path is true and filename is not an absolute path, then open
2113 * the file from where the currently processed file (if any) is located.
2116 process_file(char *filename, bool single_txn, bool use_relative_path)
2121 char relpath[MAXPGPATH];
2129 else if (strcmp(filename, "-") != 0)
2131 canonicalize_path(filename);
2134 * If we were asked to resolve the pathname relative to the location
2135 * of the currently executing script, and there is one, and this is a
2136 * relative pathname, then prepend all but the last pathname component
2137 * of the current script to this pathname.
2139 if (use_relative_path && pset.inputfile &&
2140 !is_absolute_path(filename) && !has_drive_prefix(filename))
2142 strlcpy(relpath, pset.inputfile, sizeof(relpath));
2143 get_parent_directory(relpath);
2144 join_path_components(relpath, relpath, filename);
2145 canonicalize_path(relpath);
2150 fd = fopen(filename, PG_BINARY_R);
2154 psql_error("%s: %s\n", filename, strerror(errno));
2155 return EXIT_FAILURE;
2161 filename = "<stdin>"; /* for future error messages */
2164 oldfilename = pset.inputfile;
2165 pset.inputfile = filename;
2169 if ((res = PSQLexec("BEGIN", false)) == NULL)
2171 if (pset.on_error_stop)
2181 result = MainLoop(fd);
2185 if ((res = PSQLexec("COMMIT", false)) == NULL)
2187 if (pset.on_error_stop)
2201 pset.inputfile = oldfilename;
2212 _align2string(enum printFormat in)
2219 case PRINT_UNALIGNED:
2234 case PRINT_LATEX_LONGTABLE:
2235 return "latex-longtable";
2237 case PRINT_TROFF_MS:
2246 do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
2250 Assert(param != NULL);
2253 vallen = strlen(value);
2256 if (strcmp(param, "format") == 0)
2260 else if (pg_strncasecmp("unaligned", value, vallen) == 0)
2261 popt->topt.format = PRINT_UNALIGNED;
2262 else if (pg_strncasecmp("aligned", value, vallen) == 0)
2263 popt->topt.format = PRINT_ALIGNED;
2264 else if (pg_strncasecmp("wrapped", value, vallen) == 0)
2265 popt->topt.format = PRINT_WRAPPED;
2266 else if (pg_strncasecmp("html", value, vallen) == 0)
2267 popt->topt.format = PRINT_HTML;
2268 else if (pg_strncasecmp("latex", value, vallen) == 0)
2269 popt->topt.format = PRINT_LATEX;
2270 else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
2271 popt->topt.format = PRINT_LATEX_LONGTABLE;
2272 else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
2273 popt->topt.format = PRINT_TROFF_MS;
2276 psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, latex, troff-ms\n");
2282 /* set table line style */
2283 else if (strcmp(param, "linestyle") == 0)
2287 else if (pg_strncasecmp("ascii", value, vallen) == 0)
2288 popt->topt.line_style = &pg_asciiformat;
2289 else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
2290 popt->topt.line_style = &pg_asciiformat_old;
2291 else if (pg_strncasecmp("unicode", value, vallen) == 0)
2292 popt->topt.line_style = &pg_utf8format;
2295 psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n");
2301 /* set border style/width */
2302 else if (strcmp(param, "border") == 0)
2305 popt->topt.border = atoi(value);
2309 /* set expanded/vertical mode */
2310 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
2312 if (value && pg_strcasecmp(value, "auto") == 0)
2313 popt->topt.expanded = 2;
2315 popt->topt.expanded = ParseVariableBool(value);
2317 popt->topt.expanded = !popt->topt.expanded;
2320 /* locale-aware numeric output */
2321 else if (strcmp(param, "numericlocale") == 0)
2324 popt->topt.numericLocale = ParseVariableBool(value);
2326 popt->topt.numericLocale = !popt->topt.numericLocale;
2330 else if (strcmp(param, "null") == 0)
2334 free(popt->nullPrint);
2335 popt->nullPrint = pg_strdup(value);
2339 /* field separator for unaligned text */
2340 else if (strcmp(param, "fieldsep") == 0)
2344 free(popt->topt.fieldSep.separator);
2345 popt->topt.fieldSep.separator = pg_strdup(value);
2346 popt->topt.fieldSep.separator_zero = false;
2350 else if (strcmp(param, "fieldsep_zero") == 0)
2352 free(popt->topt.fieldSep.separator);
2353 popt->topt.fieldSep.separator = NULL;
2354 popt->topt.fieldSep.separator_zero = true;
2357 /* record separator for unaligned text */
2358 else if (strcmp(param, "recordsep") == 0)
2362 free(popt->topt.recordSep.separator);
2363 popt->topt.recordSep.separator = pg_strdup(value);
2364 popt->topt.recordSep.separator_zero = false;
2368 else if (strcmp(param, "recordsep_zero") == 0)
2370 free(popt->topt.recordSep.separator);
2371 popt->topt.recordSep.separator = NULL;
2372 popt->topt.recordSep.separator_zero = true;
2375 /* toggle between full and tuples-only format */
2376 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
2379 popt->topt.tuples_only = ParseVariableBool(value);
2381 popt->topt.tuples_only = !popt->topt.tuples_only;
2384 /* set title override */
2385 else if (strcmp(param, "title") == 0)
2391 popt->title = pg_strdup(value);
2394 /* set HTML table tag options */
2395 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
2397 free(popt->topt.tableAttr);
2399 popt->topt.tableAttr = NULL;
2401 popt->topt.tableAttr = pg_strdup(value);
2404 /* toggle use of pager */
2405 else if (strcmp(param, "pager") == 0)
2407 if (value && pg_strcasecmp(value, "always") == 0)
2408 popt->topt.pager = 2;
2410 if (ParseVariableBool(value))
2411 popt->topt.pager = 1;
2413 popt->topt.pager = 0;
2414 else if (popt->topt.pager == 1)
2415 popt->topt.pager = 0;
2417 popt->topt.pager = 1;
2420 /* disable "(x rows)" footer */
2421 else if (strcmp(param, "footer") == 0)
2424 popt->topt.default_footer = ParseVariableBool(value);
2426 popt->topt.default_footer = !popt->topt.default_footer;
2429 /* set border style/width */
2430 else if (strcmp(param, "columns") == 0)
2433 popt->topt.columns = atoi(value);
2437 psql_error("\\pset: unknown option: %s\n", param);
2442 printPsetInfo(param, &pset.popt);
2449 printPsetInfo(const char *param, struct printQueryOpt *popt)
2451 Assert(param != NULL);
2453 /* show border style/width */
2454 if (strcmp(param, "border") == 0)
2456 if (!popt->topt.border)
2457 printf(_("Border style (%s) unset.\n"), param);
2459 printf(_("Border style (%s) is %d.\n"), param,
2463 /* show the target width for the wrapped format */
2464 else if (strcmp(param, "columns") == 0)
2466 if (!popt->topt.columns)
2467 printf(_("Target width (%s) unset.\n"), param);
2469 printf(_("Target width (%s) is %d.\n"), param,
2470 popt->topt.columns);
2473 /* show expanded/vertical mode */
2474 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
2476 if (popt->topt.expanded == 1)
2477 printf(_("Expanded display (%s) is on.\n"), param);
2478 else if (popt->topt.expanded == 2)
2479 printf(_("Expanded display (%s) is used automatically.\n"), param);
2481 printf(_("Expanded display (%s) is off.\n"), param);
2484 /* show field separator for unaligned text */
2485 else if (strcmp(param, "fieldsep") == 0)
2487 if (popt->topt.fieldSep.separator_zero)
2488 printf(_("Field separator (%s) is zero byte.\n"), param);
2490 printf(_("Field separator (%s) is \"%s\".\n"), param,
2491 popt->topt.fieldSep.separator);
2494 else if (strcmp(param, "fieldsep_zero") == 0)
2496 printf(_("Field separator (%s) is zero byte.\n"), param);
2499 /* show disable "(x rows)" footer */
2500 else if (strcmp(param, "footer") == 0)
2502 if (popt->topt.default_footer)
2503 printf(_("Default footer (%s) is on.\n"), param);
2505 printf(_("Default footer (%s) is off."), param);
2509 else if (strcmp(param, "format") == 0)
2511 if (!popt->topt.format)
2512 printf(_("Output format (%s) is aligned.\n"), param);
2514 printf(_("Output format (%s) is %s.\n"), param,
2515 _align2string(popt->topt.format));
2518 /* show table line style */
2519 else if (strcmp(param, "linestyle") == 0)
2521 printf(_("Line style (%s) is %s.\n"), param,
2522 get_line_style(&popt->topt)->name);
2525 /* show null display */
2526 else if (strcmp(param, "null") == 0)
2528 printf(_("Null display (%s) is \"%s\".\n"), param,
2529 popt->nullPrint ? popt->nullPrint : "");
2532 /* show locale-aware numeric output */
2533 else if (strcmp(param, "numericlocale") == 0)
2535 if (popt->topt.numericLocale)
2536 printf(_("Locale-adjusted numeric output (%s) is on.\n"), param);
2538 printf(_("Locale-adjusted numeric output (%s) is off.\n"), param);
2541 /* show toggle use of pager */
2542 else if (strcmp(param, "pager") == 0)
2544 if (popt->topt.pager == 1)
2545 printf(_("Pager (%s) is used for long output.\n"), param);
2546 else if (popt->topt.pager == 2)
2547 printf(_("Pager (%s) is always used.\n"), param);
2549 printf(_("Pager (%s) usage is off.\n"), param);
2552 /* show record separator for unaligned text */
2553 else if (strcmp(param, "recordsep") == 0)
2555 if (popt->topt.recordSep.separator_zero)
2556 printf(_("Record separator (%s) is zero byte.\n"), param);
2557 else if (strcmp(popt->topt.recordSep.separator, "\n") == 0)
2558 printf(_("Record separator (%s) is <newline>.\n"), param);
2560 printf(_("Record separator (%s) is \"%s\".\n"), param,
2561 popt->topt.recordSep.separator);
2564 else if (strcmp(param, "recordsep_zero") == 0)
2566 printf(_("Record separator (%s) is zero byte.\n"), param);
2569 /* show HTML table tag options */
2570 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
2572 if (popt->topt.tableAttr)
2573 printf(_("Table attribute (%s) is \"%s\".\n"), param,
2574 popt->topt.tableAttr);
2576 printf(_("Table attributes (%s) unset.\n"), param);
2579 /* show title override */
2580 else if (strcmp(param, "title") == 0)
2583 printf(_("Title (%s) is \"%s\".\n"), param, popt->title);
2585 printf(_("Title (%s) unset.\n"), param);
2588 /* show toggle between full and tuples-only format */
2589 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
2591 if (popt->topt.tuples_only)
2592 printf(_("Tuples only (%s) is on.\n"), param);
2594 printf(_("Tuples only (%s) is off.\n"), param);
2599 psql_error("\\pset: unknown option: %s\n", param);
2609 #define DEFAULT_SHELL "/bin/sh"
2612 * CMD.EXE is in different places in different Win32 releases so we
2613 * have to rely on the path to find it.
2615 #define DEFAULT_SHELL "cmd.exe"
2619 do_shell(const char *command)
2626 const char *shellName;
2628 shellName = getenv("SHELL");
2630 if (shellName == NULL)
2631 shellName = getenv("COMSPEC");
2633 if (shellName == NULL)
2634 shellName = DEFAULT_SHELL;
2636 /* See EDITOR handling comment for an explanation */
2638 sys = psprintf("exec %s", shellName);
2640 sys = psprintf(SYSTEMQUOTE "\"%s\"" SYSTEMQUOTE, shellName);
2642 result = system(sys);
2646 result = system(command);
2648 if (result == 127 || result == -1)
2650 psql_error("\\!: failed\n");
2657 * do_watch -- handler for \watch
2659 * We break this out of exec_command to avoid having to plaster "volatile"
2660 * onto a bunch of exec_command's variables to silence stupider compilers.
2663 do_watch(PQExpBuffer query_buf, long sleep)
2665 printQueryOpt myopt = pset.popt;
2668 if (!query_buf || query_buf->len <= 0)
2670 psql_error(_("\\watch cannot be used with an empty query\n"));
2675 * Set up rendering options, in particular, disable the pager, because
2676 * nobody wants to be prompted while watching the output of 'watch'.
2678 myopt.nullPrint = NULL;
2679 myopt.topt.pager = 0;
2688 * Prepare title for output. XXX would it be better to use the time
2689 * of completion of the command?
2692 snprintf(title, sizeof(title), _("Watch every %lds\t%s"),
2693 sleep, asctime(localtime(&timer)));
2694 myopt.title = title;
2697 * Run the query. We use PSQLexec, which is kind of cheating, but
2698 * SendQuery doesn't let us suppress autocommit behavior.
2700 res = PSQLexec(query_buf->data, false);
2702 /* PSQLexec handles failure results and returns NULL */
2707 * If SIGINT is sent while the query is processing, PSQLexec will
2708 * consume the interrupt. The user's intention, though, is to cancel
2709 * the entire watch process, so detect a sent cancellation request and
2710 * exit in this case.
2718 switch (PQresultStatus(res))
2720 case PGRES_TUPLES_OK:
2721 printQuery(res, &myopt, pset.queryFout, pset.logfile);
2724 case PGRES_COMMAND_OK:
2725 fprintf(pset.queryFout, "%s\n%s\n\n", title, PQcmdStatus(res));
2728 case PGRES_EMPTY_QUERY:
2729 psql_error(_("\\watch cannot be used with an empty query\n"));
2733 case PGRES_COPY_OUT:
2735 case PGRES_COPY_BOTH:
2736 psql_error(_("\\watch cannot be used with COPY\n"));
2741 /* other cases should have been handled by PSQLexec */
2742 psql_error(_("unexpected result status for \\watch\n"));
2749 fflush(pset.queryFout);
2752 * Set up cancellation of 'watch' via SIGINT. We redo this each time
2753 * through the loop since it's conceivable something inside PSQLexec
2754 * could change sigint_interrupt_jmp.
2756 if (sigsetjmp(sigint_interrupt_jmp, 1) != 0)
2760 * Enable 'watch' cancellations and wait a while before running the
2761 * query again. Break the sleep into short intervals since pg_usleep
2762 * isn't interruptible on some platforms.
2764 sigint_interrupt_enabled = true;
2765 for (i = 0; i < sleep; i++)
2767 pg_usleep(1000000L);
2771 sigint_interrupt_enabled = false;
2778 * This function takes a function description, e.g. "x" or "x(int)", and
2779 * issues a query on the given connection to retrieve the function's OID
2780 * using a cast to regproc or regprocedure (as appropriate). The result,
2781 * if there is one, is returned at *foid. Note that we'll fail if the
2782 * function doesn't exist OR if there are multiple matching candidates
2783 * OR if there's something syntactically wrong with the function description;
2784 * unfortunately it can be hard to tell the difference.
2787 lookup_function_oid(PGconn *conn, const char *desc, Oid *foid)
2793 query = createPQExpBuffer();
2794 printfPQExpBuffer(query, "SELECT ");
2795 appendStringLiteralConn(query, desc, conn);
2796 appendPQExpBuffer(query, "::pg_catalog.%s::pg_catalog.oid",
2797 strchr(desc, '(') ? "regprocedure" : "regproc");
2799 res = PQexec(conn, query->data);
2800 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
2801 *foid = atooid(PQgetvalue(res, 0, 0));
2804 minimal_error_message(res);
2809 destroyPQExpBuffer(query);
2815 * Fetches the "CREATE OR REPLACE FUNCTION ..." command that describes the
2816 * function with the given OID. If successful, the result is stored in buf.
2819 get_create_function_cmd(PGconn *conn, Oid oid, PQExpBuffer buf)
2825 query = createPQExpBuffer();
2826 printfPQExpBuffer(query, "SELECT pg_catalog.pg_get_functiondef(%u)", oid);
2828 res = PQexec(conn, query->data);
2829 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
2831 resetPQExpBuffer(buf);
2832 appendPQExpBufferStr(buf, PQgetvalue(res, 0, 0));
2836 minimal_error_message(res);
2841 destroyPQExpBuffer(query);
2847 * If the given argument of \ef ends with a line number, delete the line
2848 * number from the argument string and return it as an integer. (We need
2849 * this kluge because we're too lazy to parse \ef's function name argument
2850 * carefully --- we just slop it up in OT_WHOLE_LINE mode.)
2852 * Returns -1 if no line number is present, 0 on error, or a positive value
2856 strip_lineno_from_funcdesc(char *func)
2861 if (!func || func[0] == '\0')
2864 c = func + strlen(func) - 1;
2867 * This business of parsing backwards is dangerous as can be in a
2868 * multibyte environment: there is no reason to believe that we are
2869 * looking at the first byte of a character, nor are we necessarily
2870 * working in a "safe" encoding. Fortunately the bitpatterns we are
2871 * looking for are unlikely to occur as non-first bytes, but beware of
2872 * trying to expand the set of cases that can be recognized. We must
2873 * guard the <ctype.h> macros by using isascii() first, too.
2876 /* skip trailing whitespace */
2877 while (c > func && isascii((unsigned char) *c) && isspace((unsigned char) *c))
2880 /* must have a digit as last non-space char */
2881 if (c == func || !isascii((unsigned char) *c) || !isdigit((unsigned char) *c))
2884 /* find start of digit string */
2885 while (c > func && isascii((unsigned char) *c) && isdigit((unsigned char) *c))
2888 /* digits must be separated from func name by space or closing paren */
2889 /* notice also that we are not allowing an empty func name ... */
2890 if (c == func || !isascii((unsigned char) *c) ||
2891 !(isspace((unsigned char) *c) || *c == ')'))
2894 /* parse digit string */
2899 psql_error("invalid line number: %s\n", c);
2903 /* strip digit string from func */
2910 * Report just the primary error; this is to avoid cluttering the output
2911 * with, for instance, a redisplay of the internally generated query
2914 minimal_error_message(PGresult *res)
2919 msg = createPQExpBuffer();
2921 fld = PQresultErrorField(res, PG_DIAG_SEVERITY);
2923 printfPQExpBuffer(msg, "%s: ", fld);
2925 printfPQExpBuffer(msg, "ERROR: ");
2926 fld = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
2928 appendPQExpBufferStr(msg, fld);
2930 appendPQExpBufferStr(msg, "(not available)");
2931 appendPQExpBufferStr(msg, "\n");
2933 psql_error("%s", msg->data);
2935 destroyPQExpBuffer(msg);