2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2015, 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 "portability/instr_time.h"
37 #include "pqexpbuffer.h"
38 #include "dumputils.h"
45 #include "large_obj.h"
50 #include "variables.h"
53 /* functions for use in this file */
54 static backslashResult exec_command(const char *cmd,
55 PsqlScanState scan_state,
56 PQExpBuffer query_buf);
57 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
58 int lineno, bool *edited);
59 static bool do_connect(char *dbname, char *user, char *host, char *port);
60 static bool do_shell(const char *command);
61 static bool do_watch(PQExpBuffer query_buf, long sleep);
62 static bool lookup_function_oid(const char *desc, Oid *foid);
63 static bool get_create_function_cmd(Oid oid, PQExpBuffer buf);
64 static int strip_lineno_from_funcdesc(char *func);
65 static void minimal_error_message(PGresult *res);
67 static void printSSLInfo(void);
68 static bool printPsetInfo(const char *param, struct printQueryOpt *popt);
69 static char *pset_value_string(const char *param, struct printQueryOpt *popt);
72 static void checkWin32Codepage(void);
80 * Handles all the different commands that start with '\'.
81 * Ordinarily called by MainLoop().
83 * scan_state is a lexer working state that is set to continue scanning
84 * just after the '\'. The lexer is advanced past the command and all
85 * arguments on return.
87 * 'query_buf' contains the query-so-far, which may be modified by
88 * execution of the backslash command (for example, \r clears it).
89 * query_buf can be NULL if there is no query so far.
91 * Returns a status code indicating what action is desired, see command.h.
96 HandleSlashCmds(PsqlScanState scan_state,
97 PQExpBuffer query_buf)
99 backslashResult status = PSQL_CMD_SKIP_LINE;
103 Assert(scan_state != NULL);
105 /* Parse off the command name */
106 cmd = psql_scan_slash_command(scan_state);
108 /* And try to execute it */
109 status = exec_command(cmd, scan_state, query_buf);
111 if (status == PSQL_CMD_UNKNOWN)
113 if (pset.cur_cmd_interactive)
114 psql_error("Invalid command \\%s. Try \\? for help.\n", cmd);
116 psql_error("invalid command \\%s\n", cmd);
117 status = PSQL_CMD_ERROR;
120 if (status != PSQL_CMD_ERROR)
122 /* eat any remaining arguments after a valid command */
123 /* note we suppress evaluation of backticks here */
124 while ((arg = psql_scan_slash_option(scan_state,
125 OT_NO_EVAL, NULL, false)))
127 psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
133 /* silently throw away rest of line after an erroneous command */
134 while ((arg = psql_scan_slash_option(scan_state,
135 OT_WHOLE_LINE, NULL, false)))
139 /* if there is a trailing \\, swallow it */
140 psql_scan_slash_command_end(scan_state);
144 /* some commands write to queryFout, so make sure output is sent */
145 fflush(pset.queryFout);
151 * Read and interpret an argument to the \connect slash command.
154 read_connect_arg(PsqlScanState scan_state)
160 * Ideally we should treat the arguments as SQL identifiers. But for
161 * backwards compatibility with 7.2 and older pg_dump files, we have to
162 * take unquoted arguments verbatim (don't downcase them). For now,
163 * double-quoted arguments may be stripped of double quotes (as if SQL
164 * identifiers). By 7.4 or so, pg_dump files can be expected to
165 * double-quote all mixed-case \connect arguments, and then we can get rid
168 result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, "e, true);
176 if (*result == '\0' || strcmp(result, "-") == 0)
184 * Subroutine to actually try to execute a backslash command.
186 static backslashResult
187 exec_command(const char *cmd,
188 PsqlScanState scan_state,
189 PQExpBuffer query_buf)
191 bool success = true; /* indicate here if the command ran ok or
193 backslashResult status = PSQL_CMD_SKIP_LINE;
196 * \a -- toggle field alignment This makes little sense but we keep it
199 if (strcmp(cmd, "a") == 0)
201 if (pset.popt.topt.format != PRINT_ALIGNED)
202 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
204 success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
207 /* \C -- override table title (formerly change HTML caption) */
208 else if (strcmp(cmd, "C") == 0)
210 char *opt = psql_scan_slash_option(scan_state,
211 OT_NORMAL, NULL, true);
213 success = do_pset("title", opt, &pset.popt, pset.quiet);
218 * \c or \connect -- connect to database using the specified parameters.
220 * \c dbname user host port
222 * If any of these parameters are omitted or specified as '-', the current
223 * value of the parameter will be used instead. If the parameter has no
224 * current value, the default value for that parameter will be used. Some
227 * \c - - hst Connect to current database on current port of host
228 * "hst" as current user. \c - usr - prt Connect to current database on
229 * "prt" port of current host as user "usr". \c dbs Connect to
230 * "dbs" database on current port of current host as current user.
232 else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
239 opt1 = read_connect_arg(scan_state);
240 opt2 = read_connect_arg(scan_state);
241 opt3 = read_connect_arg(scan_state);
242 opt4 = read_connect_arg(scan_state);
244 success = do_connect(opt1, opt2, opt3, opt4);
253 else if (strcmp(cmd, "cd") == 0)
255 char *opt = psql_scan_slash_option(scan_state,
256 OT_NORMAL, NULL, true);
265 uid_t user_id = geteuid();
267 errno = 0; /* clear errno before call */
268 pw = getpwuid(user_id);
271 psql_error("could not get home directory for user ID %ld: %s\n",
273 errno ? strerror(errno) : _("user does not exist"));
280 * On Windows, 'cd' without arguments prints the current
281 * directory, so if someone wants to code this here instead...
287 if (chdir(dir) == -1)
289 psql_error("\\%s: could not change directory to \"%s\": %s\n",
290 cmd, dir, strerror(errno));
298 /* \conninfo -- display information about the current connection */
299 else if (strcmp(cmd, "conninfo") == 0)
301 char *db = PQdb(pset.db);
304 printf(_("You are currently not connected to a database.\n"));
308 PQconninfoOption *connOptions;
309 PQconninfoOption *option;
311 host = PQhost(pset.db);
313 host = DEFAULT_PGSOCKET_DIR;
314 /* A usable "hostaddr" overrides the basic sense of host. */
315 connOptions = PQconninfo(pset.db);
316 if (connOptions == NULL)
318 psql_error("out of memory\n");
321 for (option = connOptions; option && option->keyword; option++)
322 if (strcmp(option->keyword, "hostaddr") == 0)
324 if (option->val != NULL && option->val[0] != '\0')
329 /* If the host is an absolute path, the connection is via socket */
330 if (is_absolute_path(host))
331 printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
332 db, PQuser(pset.db), host, PQport(pset.db));
334 printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
335 db, PQuser(pset.db), host, PQport(pset.db));
338 PQconninfoFree(connOptions);
343 else if (pg_strcasecmp(cmd, "copy") == 0)
345 char *opt = psql_scan_slash_option(scan_state,
346 OT_WHOLE_LINE, NULL, false);
348 success = do_copy(opt);
353 else if (strcmp(cmd, "copyright") == 0)
357 else if (cmd[0] == 'd')
363 /* We don't do SQLID reduction on the pattern yet */
364 pattern = psql_scan_slash_option(scan_state,
365 OT_NORMAL, NULL, true);
367 show_verbose = strchr(cmd, '+') ? true : false;
368 show_system = strchr(cmd, 'S') ? true : false;
376 success = describeTableDetails(pattern, show_verbose, show_system);
378 /* standard listing of interesting things */
379 success = listTables("tvmsE", NULL, show_verbose, show_system);
382 success = describeAggregates(pattern, show_verbose, show_system);
385 success = describeTablespaces(pattern, show_verbose);
388 success = listConversions(pattern, show_verbose, show_system);
391 success = listCasts(pattern, show_verbose);
394 if (strncmp(cmd, "ddp", 3) == 0)
395 success = listDefaultACLs(pattern);
397 success = objectDescription(pattern, show_system);
400 success = listDomains(pattern, show_verbose, show_system);
402 case 'f': /* function subsystem */
412 success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
415 status = PSQL_CMD_UNKNOWN;
420 /* no longer distinct from \du */
421 success = describeRoles(pattern, show_verbose);
424 success = do_lo_list();
427 success = listLanguages(pattern, show_verbose, show_system);
430 success = listSchemas(pattern, show_verbose, show_system);
433 success = describeOperators(pattern, show_verbose, show_system);
436 success = listCollations(pattern, show_verbose, show_system);
439 success = permissionsList(pattern);
442 success = describeTypes(pattern, show_verbose, show_system);
450 success = listTables(&cmd[1], pattern, show_verbose, show_system);
453 if (cmd[2] == 'd' && cmd[3] == 's')
455 char *pattern2 = NULL;
458 pattern2 = psql_scan_slash_option(scan_state,
459 OT_NORMAL, NULL, true);
460 success = listDbRoleSettings(pattern, pattern2);
463 success = PSQL_CMD_UNKNOWN;
466 success = describeRoles(pattern, show_verbose);
468 case 'F': /* text search subsystem */
473 success = listTSConfigs(pattern, show_verbose);
476 success = listTSParsers(pattern, show_verbose);
479 success = listTSDictionaries(pattern, show_verbose);
482 success = listTSTemplates(pattern, show_verbose);
485 status = PSQL_CMD_UNKNOWN;
489 case 'e': /* SQL/MED subsystem */
493 success = listForeignServers(pattern, show_verbose);
496 success = listUserMappings(pattern, show_verbose);
499 success = listForeignDataWrappers(pattern, show_verbose);
502 success = listForeignTables(pattern, show_verbose);
505 status = PSQL_CMD_UNKNOWN;
509 case 'x': /* Extensions */
511 success = listExtensionContents(pattern);
513 success = listExtensions(pattern);
515 case 'y': /* Event Triggers */
516 success = listEventTriggers(pattern, show_verbose);
519 status = PSQL_CMD_UNKNOWN;
528 * \e or \edit -- edit the current query buffer, or edit a file and make
529 * it the query buffer
531 else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
535 psql_error("no query buffer\n");
536 status = PSQL_CMD_ERROR;
544 fname = psql_scan_slash_option(scan_state,
545 OT_NORMAL, NULL, true);
548 /* try to get separate lineno arg */
549 ln = psql_scan_slash_option(scan_state,
550 OT_NORMAL, NULL, true);
553 /* only one arg; maybe it is lineno not fname */
555 strspn(fname, "0123456789") == strlen(fname))
557 /* all digits, so assume it is lineno */
568 psql_error("invalid line number: %s\n", ln);
569 status = PSQL_CMD_ERROR;
572 if (status != PSQL_CMD_ERROR)
574 expand_tilde(&fname);
576 canonicalize_path(fname);
577 if (do_edit(fname, query_buf, lineno, NULL))
578 status = PSQL_CMD_NEWEDIT;
580 status = PSQL_CMD_ERROR;
590 * \ef -- edit the named function, or present a blank CREATE FUNCTION
591 * template if no argument is given
593 else if (strcmp(cmd, "ef") == 0)
597 if (pset.sversion < 80400)
599 psql_error("The server (version %d.%d) does not support editing function source.\n",
600 pset.sversion / 10000, (pset.sversion / 100) % 100);
601 status = PSQL_CMD_ERROR;
605 psql_error("no query buffer\n");
606 status = PSQL_CMD_ERROR;
611 Oid foid = InvalidOid;
613 func = psql_scan_slash_option(scan_state,
614 OT_WHOLE_LINE, NULL, true);
615 lineno = strip_lineno_from_funcdesc(func);
618 /* error already reported */
619 status = PSQL_CMD_ERROR;
623 /* set up an empty command to fill in */
624 printfPQExpBuffer(query_buf,
625 "CREATE FUNCTION ( )\n"
628 " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
632 else if (!lookup_function_oid(func, &foid))
634 /* error already reported */
635 status = PSQL_CMD_ERROR;
637 else if (!get_create_function_cmd(foid, query_buf))
639 /* error already reported */
640 status = PSQL_CMD_ERROR;
645 * lineno "1" should correspond to the first line of the
646 * function body. We expect that pg_get_functiondef() will
647 * emit that on a line beginning with "AS ", and that there
648 * can be no such line before the real start of the function
649 * body. Increment lineno by the number of lines before that
650 * line, so that it becomes relative to the first line of the
651 * function definition.
653 const char *lines = query_buf->data;
655 while (*lines != '\0')
657 if (strncmp(lines, "AS ", 3) == 0)
660 /* find start of next line */
661 lines = strchr(lines, '\n');
672 if (status != PSQL_CMD_ERROR)
676 if (!do_edit(NULL, query_buf, lineno, &edited))
677 status = PSQL_CMD_ERROR;
679 puts(_("No changes"));
681 status = PSQL_CMD_NEWEDIT;
685 /* \echo and \qecho */
686 else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
690 bool no_newline = false;
694 if (strcmp(cmd, "qecho") == 0)
695 fout = pset.queryFout;
699 while ((value = psql_scan_slash_option(scan_state,
700 OT_NORMAL, "ed, false)))
702 if (!quoted && strcmp(value, "-n") == 0)
718 /* \encoding -- set/show client side encoding */
719 else if (strcmp(cmd, "encoding") == 0)
721 char *encoding = psql_scan_slash_option(scan_state,
722 OT_NORMAL, NULL, false);
727 puts(pg_encoding_to_char(pset.encoding));
732 if (PQsetClientEncoding(pset.db, encoding) == -1)
733 psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
736 /* save encoding info into psql internal data */
737 pset.encoding = PQclientEncoding(pset.db);
738 pset.popt.topt.encoding = pset.encoding;
739 SetVariable(pset.vars, "ENCODING",
740 pg_encoding_to_char(pset.encoding));
746 /* \f -- change field separator */
747 else if (strcmp(cmd, "f") == 0)
749 char *fname = psql_scan_slash_option(scan_state,
750 OT_NORMAL, NULL, false);
752 success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
756 /* \g [filename] -- send query, optionally with output to file/pipe */
757 else if (strcmp(cmd, "g") == 0)
759 char *fname = psql_scan_slash_option(scan_state,
760 OT_FILEPIPE, NULL, false);
766 expand_tilde(&fname);
767 pset.gfname = pg_strdup(fname);
770 status = PSQL_CMD_SEND;
773 /* \gset [prefix] -- send query and store result into variables */
774 else if (strcmp(cmd, "gset") == 0)
776 char *prefix = psql_scan_slash_option(scan_state,
777 OT_NORMAL, NULL, false);
780 pset.gset_prefix = prefix;
783 /* we must set a non-NULL prefix to trigger storing */
784 pset.gset_prefix = pg_strdup("");
786 /* gset_prefix is freed later */
787 status = PSQL_CMD_SEND;
791 else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
793 char *opt = psql_scan_slash_option(scan_state,
794 OT_WHOLE_LINE, NULL, false);
797 /* strip any trailing spaces and semicolons */
802 (isspace((unsigned char) opt[len - 1])
803 || opt[len - 1] == ';'))
807 helpSQL(opt, pset.popt.topt.pager);
812 else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
814 if (pset.popt.topt.format != PRINT_HTML)
815 success = do_pset("format", "html", &pset.popt, pset.quiet);
817 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
821 /* \i and \ir include files */
822 else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0
823 || strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
825 char *fname = psql_scan_slash_option(scan_state,
826 OT_NORMAL, NULL, true);
830 psql_error("\\%s: missing required argument\n", cmd);
835 bool include_relative;
837 include_relative = (strcmp(cmd, "ir") == 0
838 || strcmp(cmd, "include_relative") == 0);
839 expand_tilde(&fname);
840 success = (process_file(fname, false, include_relative) == EXIT_SUCCESS);
845 /* \l is list databases */
846 else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
847 strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
852 pattern = psql_scan_slash_option(scan_state,
853 OT_NORMAL, NULL, true);
855 show_verbose = strchr(cmd, '+') ? true : false;
857 success = listAllDbs(pattern, show_verbose);
864 * large object things
866 else if (strncmp(cmd, "lo_", 3) == 0)
871 opt1 = psql_scan_slash_option(scan_state,
872 OT_NORMAL, NULL, true);
873 opt2 = psql_scan_slash_option(scan_state,
874 OT_NORMAL, NULL, true);
876 if (strcmp(cmd + 3, "export") == 0)
880 psql_error("\\%s: missing required argument\n", cmd);
886 success = do_lo_export(opt1, opt2);
890 else if (strcmp(cmd + 3, "import") == 0)
894 psql_error("\\%s: missing required argument\n", cmd);
900 success = do_lo_import(opt1, opt2);
904 else if (strcmp(cmd + 3, "list") == 0)
905 success = do_lo_list();
907 else if (strcmp(cmd + 3, "unlink") == 0)
911 psql_error("\\%s: missing required argument\n", cmd);
915 success = do_lo_unlink(opt1);
919 status = PSQL_CMD_UNKNOWN;
926 /* \o -- set query output */
927 else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
929 char *fname = psql_scan_slash_option(scan_state,
930 OT_FILEPIPE, NULL, true);
932 expand_tilde(&fname);
933 success = setQFout(fname);
937 /* \p prints the current query buffer */
938 else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
940 if (query_buf && query_buf->len > 0)
941 puts(query_buf->data);
942 else if (!pset.quiet)
943 puts(_("Query buffer is empty."));
947 /* \password -- set user password */
948 else if (strcmp(cmd, "password") == 0)
953 pw1 = simple_prompt("Enter new password: ", 100, false);
954 pw2 = simple_prompt("Enter it again: ", 100, false);
956 if (strcmp(pw1, pw2) != 0)
958 psql_error("Passwords didn't match.\n");
963 char *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true);
965 char *encrypted_password;
970 user = PQuser(pset.db);
972 encrypted_password = PQencryptPassword(pw1, user);
974 if (!encrypted_password)
976 psql_error("Password encryption failed.\n");
984 initPQExpBuffer(&buf);
985 printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
987 appendStringLiteralConn(&buf, encrypted_password, pset.db);
988 res = PSQLexec(buf.data);
989 termPQExpBuffer(&buf);
994 PQfreemem(encrypted_password);
1005 /* \prompt -- prompt and set variable */
1006 else if (strcmp(cmd, "prompt") == 0)
1009 *prompt_text = NULL;
1013 arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
1014 arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
1018 psql_error("\\%s: missing required argument\n", cmd);
1033 if (!pset.inputfile)
1034 result = simple_prompt(prompt_text, 4096, true);
1039 fputs(prompt_text, stdout);
1042 result = gets_fromFile(stdin);
1045 if (!SetVariable(pset.vars, opt, result))
1047 psql_error("\\%s: error while setting variable\n", cmd);
1058 /* \pset -- set printing parameters */
1059 else if (strcmp(cmd, "pset") == 0)
1061 char *opt0 = psql_scan_slash_option(scan_state,
1062 OT_NORMAL, NULL, false);
1063 char *opt1 = psql_scan_slash_option(scan_state,
1064 OT_NORMAL, NULL, false);
1068 /* list all variables */
1071 static const char *const my_list[] = {
1072 "border", "columns", "expanded", "fieldsep", "fieldsep_zero",
1073 "footer", "format", "linestyle", "null",
1074 "numericlocale", "pager", "pager_min_lines",
1075 "recordsep", "recordsep_zero",
1076 "tableattr", "title", "tuples_only",
1077 "unicode_border_linestyle",
1078 "unicode_column_linestyle",
1079 "unicode_header_linestyle",
1083 for (i = 0; my_list[i] != NULL; i++)
1085 char *val = pset_value_string(my_list[i], &pset.popt);
1086 printf("%-24s %s\n", my_list[i], val);
1093 success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
1100 else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
1101 status = PSQL_CMD_TERMINATE;
1103 /* reset(clear) the buffer */
1104 else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
1106 resetPQExpBuffer(query_buf);
1107 psql_scan_reset(scan_state);
1109 puts(_("Query buffer reset (cleared)."));
1112 /* \s save history in a file or show it on the screen */
1113 else if (strcmp(cmd, "s") == 0)
1115 char *fname = psql_scan_slash_option(scan_state,
1116 OT_NORMAL, NULL, true);
1118 expand_tilde(&fname);
1119 success = printHistory(fname, pset.popt.topt.pager);
1120 if (success && !pset.quiet && fname)
1121 printf(_("Wrote history to file \"%s\".\n"), fname);
1127 /* \set -- generalized set variable/option command */
1128 else if (strcmp(cmd, "set") == 0)
1130 char *opt0 = psql_scan_slash_option(scan_state,
1131 OT_NORMAL, NULL, false);
1135 /* list all variables */
1136 PrintVariables(pset.vars);
1142 * Set variable to the concatenation of the arguments.
1147 opt = psql_scan_slash_option(scan_state,
1148 OT_NORMAL, NULL, false);
1149 newval = pg_strdup(opt ? opt : "");
1152 while ((opt = psql_scan_slash_option(scan_state,
1153 OT_NORMAL, NULL, false)))
1155 newval = pg_realloc(newval, strlen(newval) + strlen(opt) + 1);
1156 strcat(newval, opt);
1160 if (!SetVariable(pset.vars, opt0, newval))
1162 psql_error("\\%s: error while setting variable\n", cmd);
1171 /* \setenv -- set environment command */
1172 else if (strcmp(cmd, "setenv") == 0)
1174 char *envvar = psql_scan_slash_option(scan_state,
1175 OT_NORMAL, NULL, false);
1176 char *envval = psql_scan_slash_option(scan_state,
1177 OT_NORMAL, NULL, false);
1181 psql_error("\\%s: missing required argument\n", cmd);
1184 else if (strchr(envvar, '=') != NULL)
1186 psql_error("\\%s: environment variable name must not contain \"=\"\n",
1192 /* No argument - unset the environment variable */
1198 /* Set variable to the value of the next argument */
1201 newval = psprintf("%s=%s", envvar, envval);
1206 * Do not free newval here, it will screw up the environment if
1207 * you do. See putenv man page for details. That means we leak a
1208 * bit of memory here, but not enough to worry about.
1215 /* \sf -- show a function's source code */
1216 else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
1218 bool show_linenumbers = (strcmp(cmd, "sf+") == 0);
1219 PQExpBuffer func_buf;
1221 Oid foid = InvalidOid;
1223 func_buf = createPQExpBuffer();
1224 func = psql_scan_slash_option(scan_state,
1225 OT_WHOLE_LINE, NULL, true);
1226 if (pset.sversion < 80400)
1228 psql_error("The server (version %d.%d) does not support showing function source.\n",
1229 pset.sversion / 10000, (pset.sversion / 100) % 100);
1230 status = PSQL_CMD_ERROR;
1234 psql_error("function name is required\n");
1235 status = PSQL_CMD_ERROR;
1237 else if (!lookup_function_oid(func, &foid))
1239 /* error already reported */
1240 status = PSQL_CMD_ERROR;
1242 else if (!get_create_function_cmd(foid, func_buf))
1244 /* error already reported */
1245 status = PSQL_CMD_ERROR;
1252 /* Select output stream: stdout, pager, or file */
1253 if (pset.queryFout == stdout)
1255 /* count lines in function to see if pager is needed */
1257 const char *lines = func_buf->data;
1259 while (*lines != '\0')
1262 /* find start of next line */
1263 lines = strchr(lines, '\n');
1269 output = PageOutput(lineno, &(pset.popt.topt));
1274 /* use previously set output file, without pager */
1275 output = pset.queryFout;
1279 if (show_linenumbers)
1281 bool in_header = true;
1283 char *lines = func_buf->data;
1286 * lineno "1" should correspond to the first line of the
1287 * function body. We expect that pg_get_functiondef() will
1288 * emit that on a line beginning with "AS ", and that there
1289 * can be no such line before the real start of the function
1292 * Note that this loop scribbles on func_buf.
1294 while (*lines != '\0')
1298 if (in_header && strncmp(lines, "AS ", 3) == 0)
1300 /* increment lineno only for body's lines */
1304 /* find and mark end of current line */
1305 eol = strchr(lines, '\n');
1309 /* show current line as appropriate */
1311 fprintf(output, " %s\n", lines);
1313 fprintf(output, "%-7d %s\n", lineno, lines);
1315 /* advance to next line, if any */
1323 /* just send the function definition to output */
1324 fputs(func_buf->data, output);
1333 destroyPQExpBuffer(func_buf);
1336 /* \t -- turn off headers and row count */
1337 else if (strcmp(cmd, "t") == 0)
1339 char *opt = psql_scan_slash_option(scan_state,
1340 OT_NORMAL, NULL, true);
1342 success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
1346 /* \T -- define html <table ...> attributes */
1347 else if (strcmp(cmd, "T") == 0)
1349 char *value = psql_scan_slash_option(scan_state,
1350 OT_NORMAL, NULL, false);
1352 success = do_pset("tableattr", value, &pset.popt, pset.quiet);
1356 /* \timing -- toggle timing of queries */
1357 else if (strcmp(cmd, "timing") == 0)
1359 char *opt = psql_scan_slash_option(scan_state,
1360 OT_NORMAL, NULL, false);
1363 pset.timing = ParseVariableBool(opt, "\\timing");
1365 pset.timing = !pset.timing;
1369 puts(_("Timing is on."));
1371 puts(_("Timing is off."));
1377 else if (strcmp(cmd, "unset") == 0)
1379 char *opt = psql_scan_slash_option(scan_state,
1380 OT_NORMAL, NULL, false);
1384 psql_error("\\%s: missing required argument\n", cmd);
1387 else if (!SetVariable(pset.vars, opt, NULL))
1389 psql_error("\\%s: error while setting variable\n", cmd);
1395 /* \w -- write query buffer to file */
1396 else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
1399 bool is_pipe = false;
1404 psql_error("no query buffer\n");
1405 status = PSQL_CMD_ERROR;
1409 fname = psql_scan_slash_option(scan_state,
1410 OT_FILEPIPE, NULL, true);
1411 expand_tilde(&fname);
1415 psql_error("\\%s: missing required argument\n", cmd);
1420 if (fname[0] == '|')
1423 fd = popen(&fname[1], "w");
1427 canonicalize_path(fname);
1428 fd = fopen(fname, "w");
1432 psql_error("%s: %s\n", fname, strerror(errno));
1442 if (query_buf && query_buf->len > 0)
1443 fprintf(fd, "%s\n", query_buf->data);
1446 result = pclose(fd);
1448 result = fclose(fd);
1452 psql_error("%s: %s\n", fname, strerror(errno));
1460 /* \watch -- execute a query every N seconds */
1461 else if (strcmp(cmd, "watch") == 0)
1463 char *opt = psql_scan_slash_option(scan_state,
1464 OT_NORMAL, NULL, true);
1467 /* Convert optional sleep-length argument */
1470 sleep = strtol(opt, NULL, 10);
1476 success = do_watch(query_buf, sleep);
1478 /* Reset the query buffer as though for \r */
1479 resetPQExpBuffer(query_buf);
1480 psql_scan_reset(scan_state);
1483 /* \x -- set or toggle expanded table representation */
1484 else if (strcmp(cmd, "x") == 0)
1486 char *opt = psql_scan_slash_option(scan_state,
1487 OT_NORMAL, NULL, true);
1489 success = do_pset("expanded", opt, &pset.popt, pset.quiet);
1493 /* \z -- list table rights (equivalent to \dp) */
1494 else if (strcmp(cmd, "z") == 0)
1496 char *pattern = psql_scan_slash_option(scan_state,
1497 OT_NORMAL, NULL, true);
1499 success = permissionsList(pattern);
1504 /* \! -- shell escape */
1505 else if (strcmp(cmd, "!") == 0)
1507 char *opt = psql_scan_slash_option(scan_state,
1508 OT_WHOLE_LINE, NULL, false);
1510 success = do_shell(opt);
1514 /* \? -- slash command help */
1515 else if (strcmp(cmd, "?") == 0)
1517 char *opt0 = psql_scan_slash_option(scan_state,
1518 OT_NORMAL, NULL, false);
1520 if (!opt0 || strcmp(opt0, "commands") == 0)
1521 slashUsage(pset.popt.topt.pager);
1522 else if (strcmp(opt0, "options") == 0)
1523 usage(pset.popt.topt.pager);
1524 else if (strcmp(opt0, "variables") == 0)
1525 helpVariables(pset.popt.topt.pager);
1527 slashUsage(pset.popt.topt.pager);
1533 * These commands don't do anything. I just use them to test the parser.
1535 else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
1540 while ((value = psql_scan_slash_option(scan_state,
1541 OT_NORMAL, NULL, true)))
1543 psql_error("+ opt(%d) = |%s|\n", i++, value);
1550 status = PSQL_CMD_UNKNOWN;
1553 status = PSQL_CMD_ERROR;
1559 * Ask the user for a password; 'username' is the username the
1560 * password is for, if one has been explicitly specified. Returns a
1564 prompt_for_password(const char *username)
1568 if (username == NULL)
1569 result = simple_prompt("Password: ", 100, false);
1574 prompt_text = psprintf(_("Password for user %s: "), username);
1575 result = simple_prompt(prompt_text, 100, false);
1583 param_is_newly_set(const char *old_val, const char *new_val)
1585 if (new_val == NULL)
1588 if (old_val == NULL || strcmp(old_val, new_val) != 0)
1595 * do_connect -- handler for \connect
1597 * Connects to a database with given parameters. If there exists an
1598 * established connection, NULL values will be replaced with the ones
1599 * in the current connection. Otherwise NULL will be passed for that
1600 * parameter to PQconnectdbParams(), so the libpq defaults will be used.
1602 * In interactive mode, if connection fails with the given parameters,
1603 * the old connection will be kept.
1606 do_connect(char *dbname, char *user, char *host, char *port)
1608 PGconn *o_conn = pset.db,
1610 char *password = NULL;
1612 if (!o_conn && (!dbname || !user || !host || !port))
1615 * We don't know the supplied connection parameters and don't want to
1616 * connect to the wrong database by using defaults, so require all
1617 * parameters to be specified.
1619 psql_error("All connection parameters must be supplied because no "
1620 "database connection exists\n");
1625 dbname = PQdb(o_conn);
1627 user = PQuser(o_conn);
1629 host = PQhost(o_conn);
1631 port = PQport(o_conn);
1634 * If the user asked to be prompted for a password, ask for one now. If
1635 * not, use the password from the old connection, provided the username
1636 * has not changed. Otherwise, try to connect without a password first,
1637 * and then ask for a password if needed.
1639 * XXX: this behavior leads to spurious connection attempts recorded in
1640 * the postmaster's log. But libpq offers no API that would let us obtain
1641 * a password and then continue with the first connection attempt.
1643 if (pset.getPassword == TRI_YES)
1645 password = prompt_for_password(user);
1647 else if (o_conn && user && strcmp(PQuser(o_conn), user) == 0)
1649 password = pg_strdup(PQpass(o_conn));
1654 #define PARAMS_ARRAY_SIZE 8
1655 const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
1656 const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
1658 keywords[0] = "host";
1660 keywords[1] = "port";
1662 keywords[2] = "user";
1664 keywords[3] = "password";
1665 values[3] = password;
1666 keywords[4] = "dbname";
1668 keywords[5] = "fallback_application_name";
1669 values[5] = pset.progname;
1670 keywords[6] = "client_encoding";
1671 values[6] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto";
1675 n_conn = PQconnectdbParams(keywords, values, true);
1680 /* We can immediately discard the password -- no longer needed */
1684 if (PQstatus(n_conn) == CONNECTION_OK)
1688 * Connection attempt failed; either retry the connection attempt with
1689 * a new password, or give up.
1691 if (!password && PQconnectionNeedsPassword(n_conn) && pset.getPassword != TRI_NO)
1694 password = prompt_for_password(user);
1699 * Failed to connect to the database. In interactive mode, keep the
1700 * previous connection to the DB; in scripting mode, close our
1701 * previous connection as well.
1703 if (pset.cur_cmd_interactive)
1705 psql_error("%s", PQerrorMessage(n_conn));
1707 /* pset.db is left unmodified */
1709 psql_error("Previous connection kept\n");
1713 psql_error("\\connect: %s", PQerrorMessage(n_conn));
1726 * Replace the old connection with the new one, and update
1727 * connection-dependent variables.
1729 PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
1732 connection_warnings(false); /* Must be after SyncVariables */
1734 /* Tell the user about the new connection */
1737 if (param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) ||
1738 param_is_newly_set(PQport(o_conn), PQport(pset.db)))
1740 char *host = PQhost(pset.db);
1743 host = DEFAULT_PGSOCKET_DIR;
1744 /* If the host is an absolute path, the connection is via socket */
1745 if (is_absolute_path(host))
1746 printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
1747 PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
1749 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
1750 PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
1753 printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
1754 PQdb(pset.db), PQuser(pset.db));
1764 connection_warnings(bool in_startup)
1766 if (!pset.quiet && !pset.notty)
1768 int client_ver = PG_VERSION_NUM;
1770 if (pset.sversion != client_ver)
1772 const char *server_version;
1773 char server_ver_str[16];
1775 /* Try to get full text form, might include "devel" etc */
1776 server_version = PQparameterStatus(pset.db, "server_version");
1777 if (!server_version)
1779 snprintf(server_ver_str, sizeof(server_ver_str),
1781 pset.sversion / 10000,
1782 (pset.sversion / 100) % 100,
1783 pset.sversion % 100);
1784 server_version = server_ver_str;
1787 printf(_("%s (%s, server %s)\n"),
1788 pset.progname, PG_VERSION, server_version);
1790 /* For version match, only print psql banner on startup. */
1791 else if (in_startup)
1792 printf("%s (%s)\n", pset.progname, PG_VERSION);
1794 if (pset.sversion / 100 > client_ver / 100)
1795 printf(_("WARNING: %s major version %d.%d, server major version %d.%d.\n"
1796 " Some psql features might not work.\n"),
1797 pset.progname, client_ver / 10000, (client_ver / 100) % 100,
1798 pset.sversion / 10000, (pset.sversion / 100) % 100);
1801 checkWin32Codepage();
1811 * Prints information about the current SSL connection, if SSL is in use
1816 const char *protocol;
1819 const char *compression;
1821 if (!PQsslInUse(pset.db))
1822 return; /* no SSL */
1824 protocol = PQsslAttribute(pset.db, "protocol");
1825 cipher = PQsslAttribute(pset.db, "cipher");
1826 bits = PQsslAttribute(pset.db, "key_bits");
1827 compression = PQsslAttribute(pset.db, "compression");
1829 printf(_("SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n"),
1830 protocol ? protocol : _("unknown"),
1831 cipher ? cipher : _("unknown"),
1832 bits ? bits : _("unknown"),
1833 (compression && strcmp(compression, "off") != 0) ? _("on") : _("off"));
1838 * checkWin32Codepage
1840 * Prints a warning when win32 console codepage differs from Windows codepage
1844 checkWin32Codepage(void)
1850 concp = GetConsoleCP();
1853 printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
1854 " 8-bit characters might not work correctly. See psql reference\n"
1855 " page \"Notes for Windows users\" for details.\n"),
1865 * Make psql's internal variables agree with connection state upon
1866 * establishing a new connection.
1871 /* get stuff from connection */
1872 pset.encoding = PQclientEncoding(pset.db);
1873 pset.popt.topt.encoding = pset.encoding;
1874 pset.sversion = PQserverVersion(pset.db);
1876 SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
1877 SetVariable(pset.vars, "USER", PQuser(pset.db));
1878 SetVariable(pset.vars, "HOST", PQhost(pset.db));
1879 SetVariable(pset.vars, "PORT", PQport(pset.db));
1880 SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
1882 /* send stuff to it, too */
1883 PQsetErrorVerbosity(pset.db, pset.verbosity);
1889 * Clear variables that should be not be set when there is no connection.
1892 UnsyncVariables(void)
1894 SetVariable(pset.vars, "DBNAME", NULL);
1895 SetVariable(pset.vars, "USER", NULL);
1896 SetVariable(pset.vars, "HOST", NULL);
1897 SetVariable(pset.vars, "PORT", NULL);
1898 SetVariable(pset.vars, "ENCODING", NULL);
1903 * do_edit -- handler for \e
1905 * If you do not specify a filename, the current query buffer will be copied
1906 * into a temporary one.
1909 editFile(const char *fname, int lineno)
1911 const char *editorName;
1912 const char *editor_lineno_arg = NULL;
1916 Assert(fname != NULL);
1918 /* Find an editor to use */
1919 editorName = getenv("PSQL_EDITOR");
1921 editorName = getenv("EDITOR");
1923 editorName = getenv("VISUAL");
1925 editorName = DEFAULT_EDITOR;
1927 /* Get line number argument, if we need it. */
1930 editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
1931 #ifdef DEFAULT_EDITOR_LINENUMBER_ARG
1932 if (!editor_lineno_arg)
1933 editor_lineno_arg = DEFAULT_EDITOR_LINENUMBER_ARG;
1935 if (!editor_lineno_arg)
1937 psql_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n");
1943 * On Unix the EDITOR value should *not* be quoted, since it might include
1944 * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
1945 * if necessary. But this policy is not very workable on Windows, due to
1946 * severe brain damage in their command shell plus the fact that standard
1947 * program paths include spaces.
1951 sys = psprintf("exec %s %s%d '%s'",
1952 editorName, editor_lineno_arg, lineno, fname);
1954 sys = psprintf("exec %s '%s'",
1958 sys = psprintf("\"%s\" %s%d \"%s\"",
1959 editorName, editor_lineno_arg, lineno, fname);
1961 sys = psprintf("\"%s\" \"%s\"",
1964 result = system(sys);
1966 psql_error("could not start editor \"%s\"\n", editorName);
1967 else if (result == 127)
1968 psql_error("could not start /bin/sh\n");
1977 do_edit(const char *filename_arg, PQExpBuffer query_buf,
1978 int lineno, bool *edited)
1980 char fnametmp[MAXPGPATH];
1981 FILE *stream = NULL;
1990 fname = filename_arg;
1993 /* make a temp file to edit */
1995 const char *tmpdir = getenv("TMPDIR");
2000 char tmpdir[MAXPGPATH];
2003 ret = GetTempPath(MAXPGPATH, tmpdir);
2004 if (ret == 0 || ret > MAXPGPATH)
2006 psql_error("could not locate temporary directory: %s\n",
2007 !ret ? strerror(errno) : "");
2012 * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
2013 * current directory to the supplied path unless we use only
2014 * backslashes, so we do that.
2018 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
2019 "/", (int) getpid());
2021 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
2022 "" /* trailing separator already present */ , (int) getpid());
2025 fname = (const char *) fnametmp;
2027 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
2029 stream = fdopen(fd, "w");
2031 if (fd == -1 || !stream)
2033 psql_error("could not open temporary file \"%s\": %s\n", fname, strerror(errno));
2038 unsigned int ql = query_buf->len;
2040 if (ql == 0 || query_buf->data[ql - 1] != '\n')
2042 appendPQExpBufferChar(query_buf, '\n');
2046 if (fwrite(query_buf->data, 1, ql, stream) != ql)
2048 psql_error("%s: %s\n", fname, strerror(errno));
2050 if (fclose(stream) != 0)
2051 psql_error("%s: %s\n", fname, strerror(errno));
2053 if (remove(fname) != 0)
2054 psql_error("%s: %s\n", fname, strerror(errno));
2058 else if (fclose(stream) != 0)
2060 psql_error("%s: %s\n", fname, strerror(errno));
2061 if (remove(fname) != 0)
2062 psql_error("%s: %s\n", fname, strerror(errno));
2068 if (!error && stat(fname, &before) != 0)
2070 psql_error("%s: %s\n", fname, strerror(errno));
2076 error = !editFile(fname, lineno);
2078 if (!error && stat(fname, &after) != 0)
2080 psql_error("%s: %s\n", fname, strerror(errno));
2084 if (!error && before.st_mtime != after.st_mtime)
2086 stream = fopen(fname, PG_BINARY_R);
2089 psql_error("%s: %s\n", fname, strerror(errno));
2094 /* read file back into query_buf */
2097 resetPQExpBuffer(query_buf);
2098 while (fgets(line, sizeof(line), stream) != NULL)
2099 appendPQExpBufferStr(query_buf, line);
2103 psql_error("%s: %s\n", fname, strerror(errno));
2115 /* remove temp file */
2118 if (remove(fname) == -1)
2120 psql_error("%s: %s\n", fname, strerror(errno));
2133 * Reads commands from filename and passes them to the main processing loop.
2134 * Handler for \i and \ir, but can be used for other things as well. Returns
2135 * MainLoop() error code.
2137 * If use_relative_path is true and filename is not an absolute path, then open
2138 * the file from where the currently processed file (if any) is located.
2141 process_file(char *filename, bool single_txn, bool use_relative_path)
2146 char relpath[MAXPGPATH];
2154 else if (strcmp(filename, "-") != 0)
2156 canonicalize_path(filename);
2159 * If we were asked to resolve the pathname relative to the location
2160 * of the currently executing script, and there is one, and this is a
2161 * relative pathname, then prepend all but the last pathname component
2162 * of the current script to this pathname.
2164 if (use_relative_path && pset.inputfile &&
2165 !is_absolute_path(filename) && !has_drive_prefix(filename))
2167 strlcpy(relpath, pset.inputfile, sizeof(relpath));
2168 get_parent_directory(relpath);
2169 join_path_components(relpath, relpath, filename);
2170 canonicalize_path(relpath);
2175 fd = fopen(filename, PG_BINARY_R);
2179 psql_error("%s: %s\n", filename, strerror(errno));
2180 return EXIT_FAILURE;
2186 filename = "<stdin>"; /* for future error messages */
2189 oldfilename = pset.inputfile;
2190 pset.inputfile = filename;
2194 if ((res = PSQLexec("BEGIN")) == NULL)
2196 if (pset.on_error_stop)
2206 result = MainLoop(fd);
2210 if ((res = PSQLexec("COMMIT")) == NULL)
2212 if (pset.on_error_stop)
2226 pset.inputfile = oldfilename;
2233 _align2string(enum printFormat in)
2240 case PRINT_UNALIGNED:
2252 case PRINT_ASCIIDOC:
2258 case PRINT_LATEX_LONGTABLE:
2259 return "latex-longtable";
2261 case PRINT_TROFF_MS:
2269 * Parse entered unicode linestyle. Returns true, when entered string is
2270 * known linestyle: single, double else returns false.
2273 set_unicode_line_style(printQueryOpt *popt, const char *value, size_t vallen,
2274 unicode_linestyle *linestyle)
2276 if (pg_strncasecmp("single", value, vallen) == 0)
2277 *linestyle = UNICODE_LINESTYLE_SINGLE;
2278 else if (pg_strncasecmp("double", value, vallen) == 0)
2279 *linestyle = UNICODE_LINESTYLE_DOUBLE;
2283 /* input is ok, generate new unicode style */
2284 refresh_utf8format(&(popt->topt));
2290 _unicode_linestyle2string(int linestyle)
2294 case UNICODE_LINESTYLE_SINGLE:
2297 case UNICODE_LINESTYLE_DOUBLE:
2309 do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
2313 Assert(param != NULL);
2316 vallen = strlen(value);
2319 if (strcmp(param, "format") == 0)
2323 else if (pg_strncasecmp("unaligned", value, vallen) == 0)
2324 popt->topt.format = PRINT_UNALIGNED;
2325 else if (pg_strncasecmp("aligned", value, vallen) == 0)
2326 popt->topt.format = PRINT_ALIGNED;
2327 else if (pg_strncasecmp("wrapped", value, vallen) == 0)
2328 popt->topt.format = PRINT_WRAPPED;
2329 else if (pg_strncasecmp("html", value, vallen) == 0)
2330 popt->topt.format = PRINT_HTML;
2331 else if (pg_strncasecmp("asciidoc", value, vallen) == 0)
2332 popt->topt.format = PRINT_ASCIIDOC;
2333 else if (pg_strncasecmp("latex", value, vallen) == 0)
2334 popt->topt.format = PRINT_LATEX;
2335 else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
2336 popt->topt.format = PRINT_LATEX_LONGTABLE;
2337 else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
2338 popt->topt.format = PRINT_TROFF_MS;
2341 psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, troff-ms\n");
2347 /* set table line style */
2348 else if (strcmp(param, "linestyle") == 0)
2352 else if (pg_strncasecmp("ascii", value, vallen) == 0)
2353 popt->topt.line_style = &pg_asciiformat;
2354 else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
2355 popt->topt.line_style = &pg_asciiformat_old;
2356 else if (pg_strncasecmp("unicode", value, vallen) == 0)
2357 popt->topt.line_style = &pg_utf8format;
2360 psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n");
2366 /* set unicode border line style */
2367 else if (strcmp(param, "unicode_border_linestyle") == 0)
2371 else if (!set_unicode_line_style(popt, value, vallen,
2372 &popt->topt.unicode_border_linestyle))
2374 psql_error("\\pset: allowed unicode border linestyle are single, double\n");
2379 /* set unicode column line style */
2380 else if (strcmp(param, "unicode_column_linestyle") == 0)
2384 else if (!set_unicode_line_style(popt, value, vallen,
2385 &popt->topt.unicode_column_linestyle))
2387 psql_error("\\pset: allowed unicode column linestyle are single, double\n");
2392 /* set unicode header line style */
2393 else if (strcmp(param, "unicode_header_linestyle") == 0)
2397 else if (!set_unicode_line_style(popt, value, vallen,
2398 &popt->topt.unicode_header_linestyle))
2400 psql_error("\\pset: allowed unicode header linestyle are single, double\n");
2405 /* set border style/width */
2406 else if (strcmp(param, "border") == 0)
2409 popt->topt.border = atoi(value);
2413 /* set expanded/vertical mode */
2414 else if (strcmp(param, "x") == 0 ||
2415 strcmp(param, "expanded") == 0 ||
2416 strcmp(param, "vertical") == 0)
2418 if (value && pg_strcasecmp(value, "auto") == 0)
2419 popt->topt.expanded = 2;
2421 popt->topt.expanded = ParseVariableBool(value, param);
2423 popt->topt.expanded = !popt->topt.expanded;
2426 /* locale-aware numeric output */
2427 else if (strcmp(param, "numericlocale") == 0)
2430 popt->topt.numericLocale = ParseVariableBool(value, param);
2432 popt->topt.numericLocale = !popt->topt.numericLocale;
2436 else if (strcmp(param, "null") == 0)
2440 free(popt->nullPrint);
2441 popt->nullPrint = pg_strdup(value);
2445 /* field separator for unaligned text */
2446 else if (strcmp(param, "fieldsep") == 0)
2450 free(popt->topt.fieldSep.separator);
2451 popt->topt.fieldSep.separator = pg_strdup(value);
2452 popt->topt.fieldSep.separator_zero = false;
2456 else if (strcmp(param, "fieldsep_zero") == 0)
2458 free(popt->topt.fieldSep.separator);
2459 popt->topt.fieldSep.separator = NULL;
2460 popt->topt.fieldSep.separator_zero = true;
2463 /* record separator for unaligned text */
2464 else if (strcmp(param, "recordsep") == 0)
2468 free(popt->topt.recordSep.separator);
2469 popt->topt.recordSep.separator = pg_strdup(value);
2470 popt->topt.recordSep.separator_zero = false;
2474 else if (strcmp(param, "recordsep_zero") == 0)
2476 free(popt->topt.recordSep.separator);
2477 popt->topt.recordSep.separator = NULL;
2478 popt->topt.recordSep.separator_zero = true;
2481 /* toggle between full and tuples-only format */
2482 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
2485 popt->topt.tuples_only = ParseVariableBool(value, param);
2487 popt->topt.tuples_only = !popt->topt.tuples_only;
2490 /* set title override */
2491 else if (strcmp(param, "title") == 0)
2497 popt->title = pg_strdup(value);
2500 /* set HTML table tag options */
2501 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
2503 free(popt->topt.tableAttr);
2505 popt->topt.tableAttr = NULL;
2507 popt->topt.tableAttr = pg_strdup(value);
2510 /* toggle use of pager */
2511 else if (strcmp(param, "pager") == 0)
2513 if (value && pg_strcasecmp(value, "always") == 0)
2514 popt->topt.pager = 2;
2517 if (ParseVariableBool(value, param))
2518 popt->topt.pager = 1;
2520 popt->topt.pager = 0;
2522 else if (popt->topt.pager == 1)
2523 popt->topt.pager = 0;
2525 popt->topt.pager = 1;
2528 /* set minimum lines for pager use */
2529 else if (strcmp(param, "pager_min_lines") == 0)
2532 popt->topt.pager_min_lines = atoi(value);
2535 /* disable "(x rows)" footer */
2536 else if (strcmp(param, "footer") == 0)
2539 popt->topt.default_footer = ParseVariableBool(value, param);
2541 popt->topt.default_footer = !popt->topt.default_footer;
2544 /* set border style/width */
2545 else if (strcmp(param, "columns") == 0)
2548 popt->topt.columns = atoi(value);
2552 psql_error("\\pset: unknown option: %s\n", param);
2557 printPsetInfo(param, &pset.popt);
2564 printPsetInfo(const char *param, struct printQueryOpt *popt)
2566 Assert(param != NULL);
2568 /* show border style/width */
2569 if (strcmp(param, "border") == 0)
2570 printf(_("Border style is %d.\n"), popt->topt.border);
2572 /* show the target width for the wrapped format */
2573 else if (strcmp(param, "columns") == 0)
2575 if (!popt->topt.columns)
2576 printf(_("Target width is unset.\n"));
2578 printf(_("Target width is %d.\n"), popt->topt.columns);
2581 /* show expanded/vertical mode */
2582 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
2584 if (popt->topt.expanded == 1)
2585 printf(_("Expanded display is on.\n"));
2586 else if (popt->topt.expanded == 2)
2587 printf(_("Expanded display is used automatically.\n"));
2589 printf(_("Expanded display is off.\n"));
2592 /* show field separator for unaligned text */
2593 else if (strcmp(param, "fieldsep") == 0)
2595 if (popt->topt.fieldSep.separator_zero)
2596 printf(_("Field separator is zero byte.\n"));
2598 printf(_("Field separator is \"%s\".\n"),
2599 popt->topt.fieldSep.separator);
2602 else if (strcmp(param, "fieldsep_zero") == 0)
2604 printf(_("Field separator is zero byte.\n"));
2607 /* show disable "(x rows)" footer */
2608 else if (strcmp(param, "footer") == 0)
2610 if (popt->topt.default_footer)
2611 printf(_("Default footer is on.\n"));
2613 printf(_("Default footer is off.\n"));
2617 else if (strcmp(param, "format") == 0)
2619 printf(_("Output format is %s.\n"), _align2string(popt->topt.format));
2622 /* show table line style */
2623 else if (strcmp(param, "linestyle") == 0)
2625 printf(_("Line style is %s.\n"),
2626 get_line_style(&popt->topt)->name);
2629 /* show null display */
2630 else if (strcmp(param, "null") == 0)
2632 printf(_("Null display is \"%s\".\n"),
2633 popt->nullPrint ? popt->nullPrint : "");
2636 /* show locale-aware numeric output */
2637 else if (strcmp(param, "numericlocale") == 0)
2639 if (popt->topt.numericLocale)
2640 printf(_("Locale-adjusted numeric output is on.\n"));
2642 printf(_("Locale-adjusted numeric output is off.\n"));
2645 /* show toggle use of pager */
2646 else if (strcmp(param, "pager") == 0)
2648 if (popt->topt.pager == 1)
2649 printf(_("Pager is used for long output.\n"));
2650 else if (popt->topt.pager == 2)
2651 printf(_("Pager is always used.\n"));
2653 printf(_("Pager usage is off.\n"));
2656 /* show minimum lines for pager use */
2657 else if (strcmp(param, "pager_min_lines") == 0)
2659 printf(_("Pager won't be used for less than %d lines\n"),
2660 popt->topt.pager_min_lines);
2663 /* show record separator for unaligned text */
2664 else if (strcmp(param, "recordsep") == 0)
2666 if (popt->topt.recordSep.separator_zero)
2667 printf(_("Record separator is zero byte.\n"));
2668 else if (strcmp(popt->topt.recordSep.separator, "\n") == 0)
2669 printf(_("Record separator is <newline>.\n"));
2671 printf(_("Record separator is \"%s\".\n"),
2672 popt->topt.recordSep.separator);
2675 else if (strcmp(param, "recordsep_zero") == 0)
2677 printf(_("Record separator is zero byte.\n"));
2680 /* show HTML table tag options */
2681 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
2683 if (popt->topt.tableAttr)
2684 printf(_("Table attributes are \"%s\".\n"),
2685 popt->topt.tableAttr);
2687 printf(_("Table attributes unset.\n"));
2690 /* show title override */
2691 else if (strcmp(param, "title") == 0)
2694 printf(_("Title is \"%s\".\n"), popt->title);
2696 printf(_("Title is unset.\n"));
2699 /* show toggle between full and tuples-only format */
2700 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
2702 if (popt->topt.tuples_only)
2703 printf(_("Tuples only is on.\n"));
2705 printf(_("Tuples only is off.\n"));
2708 /* unicode style formatting */
2709 else if (strcmp(param, "unicode_border_linestyle") == 0)
2711 printf(_("Unicode border linestyle is \"%s\".\n"),
2712 _unicode_linestyle2string(popt->topt.unicode_border_linestyle));
2715 else if (strcmp(param, "unicode_column_linestyle") == 0)
2717 printf(_("Unicode column linestyle is \"%s\".\n"),
2718 _unicode_linestyle2string(popt->topt.unicode_column_linestyle));
2721 else if (strcmp(param, "unicode_header_linestyle") == 0)
2723 printf(_("Unicode border linestyle is \"%s\".\n"),
2724 _unicode_linestyle2string(popt->topt.unicode_header_linestyle));
2729 psql_error("\\pset: unknown option: %s\n", param);
2738 pset_bool_string(bool val)
2740 return val ? "on" : "off";
2745 pset_quoted_string(const char *str)
2747 char *ret = pg_malloc(strlen(str) * 2 + 3);
2759 else if (*str == '\'')
2776 * Return a malloc'ed string for the \pset value.
2778 * Note that for some string parameters, print.c distinguishes between unset
2779 * and empty string, but for others it doesn't. This function should produce
2780 * output that produces the correct setting when fed back into \pset.
2783 pset_value_string(const char *param, struct printQueryOpt *popt)
2785 Assert(param != NULL);
2787 if (strcmp(param, "border") == 0)
2788 return psprintf("%d", popt->topt.border);
2789 else if (strcmp(param, "columns") == 0)
2790 return psprintf("%d", popt->topt.columns);
2791 else if (strcmp(param, "expanded") == 0)
2792 return pstrdup(popt->topt.expanded == 2
2794 : pset_bool_string(popt->topt.expanded));
2795 else if (strcmp(param, "fieldsep") == 0)
2796 return pset_quoted_string(popt->topt.fieldSep.separator
2797 ? popt->topt.fieldSep.separator
2799 else if (strcmp(param, "fieldsep_zero") == 0)
2800 return pstrdup(pset_bool_string(popt->topt.fieldSep.separator_zero));
2801 else if (strcmp(param, "footer") == 0)
2802 return pstrdup(pset_bool_string(popt->topt.default_footer));
2803 else if (strcmp(param, "format") == 0)
2804 return psprintf("%s", _align2string(popt->topt.format));
2805 else if (strcmp(param, "linestyle") == 0)
2806 return psprintf("%s", get_line_style(&popt->topt)->name);
2807 else if (strcmp(param, "null") == 0)
2808 return pset_quoted_string(popt->nullPrint
2811 else if (strcmp(param, "numericlocale") == 0)
2812 return pstrdup(pset_bool_string(popt->topt.numericLocale));
2813 else if (strcmp(param, "pager") == 0)
2814 return psprintf("%d", popt->topt.pager);
2815 else if (strcmp(param, "pager_min_lines") == 0)
2816 return psprintf("%d", popt->topt.pager_min_lines);
2817 else if (strcmp(param, "recordsep") == 0)
2818 return pset_quoted_string(popt->topt.recordSep.separator
2819 ? popt->topt.recordSep.separator
2821 else if (strcmp(param, "recordsep_zero") == 0)
2822 return pstrdup(pset_bool_string(popt->topt.recordSep.separator_zero));
2823 else if (strcmp(param, "tableattr") == 0)
2824 return popt->topt.tableAttr ? pset_quoted_string(popt->topt.tableAttr) : pstrdup("");
2825 else if (strcmp(param, "title") == 0)
2826 return popt->title ? pset_quoted_string(popt->title) : pstrdup("");
2827 else if (strcmp(param, "tuples_only") == 0)
2828 return pstrdup(pset_bool_string(popt->topt.tuples_only));
2829 else if (strcmp(param, "unicode_border_linestyle") == 0)
2830 return pstrdup(_unicode_linestyle2string(popt->topt.unicode_border_linestyle));
2831 else if (strcmp(param, "unicode_column_linestyle") == 0)
2832 return pstrdup(_unicode_linestyle2string(popt->topt.unicode_column_linestyle));
2833 else if (strcmp(param, "unicode_header_linestyle") == 0)
2834 return pstrdup(_unicode_linestyle2string(popt->topt.unicode_header_linestyle));
2836 return pstrdup("ERROR");
2842 #define DEFAULT_SHELL "/bin/sh"
2845 * CMD.EXE is in different places in different Win32 releases so we
2846 * have to rely on the path to find it.
2848 #define DEFAULT_SHELL "cmd.exe"
2852 do_shell(const char *command)
2859 const char *shellName;
2861 shellName = getenv("SHELL");
2863 if (shellName == NULL)
2864 shellName = getenv("COMSPEC");
2866 if (shellName == NULL)
2867 shellName = DEFAULT_SHELL;
2869 /* See EDITOR handling comment for an explanation */
2871 sys = psprintf("exec %s", shellName);
2873 sys = psprintf("\"%s\"", shellName);
2875 result = system(sys);
2879 result = system(command);
2881 if (result == 127 || result == -1)
2883 psql_error("\\!: failed\n");
2890 * do_watch -- handler for \watch
2892 * We break this out of exec_command to avoid having to plaster "volatile"
2893 * onto a bunch of exec_command's variables to silence stupider compilers.
2896 do_watch(PQExpBuffer query_buf, long sleep)
2898 printQueryOpt myopt = pset.popt;
2901 if (!query_buf || query_buf->len <= 0)
2903 psql_error(_("\\watch cannot be used with an empty query\n"));
2908 * Set up rendering options, in particular, disable the pager, because
2909 * nobody wants to be prompted while watching the output of 'watch'.
2911 myopt.topt.pager = 0;
2920 * Prepare title for output. XXX would it be better to use the time
2921 * of completion of the command?
2924 snprintf(title, sizeof(title), _("Watch every %lds\t%s"),
2925 sleep, asctime(localtime(&timer)));
2926 myopt.title = title;
2928 /* Run the query and print out the results */
2929 res = PSQLexecWatch(query_buf->data, &myopt);
2932 * PSQLexecWatch handles the case where we can no longer
2933 * repeat the query, and returns 0 or -1.
2941 * Set up cancellation of 'watch' via SIGINT. We redo this each time
2942 * through the loop since it's conceivable something inside
2943 * PSQLexecWatch could change sigint_interrupt_jmp.
2945 if (sigsetjmp(sigint_interrupt_jmp, 1) != 0)
2949 * Enable 'watch' cancellations and wait a while before running the
2950 * query again. Break the sleep into short intervals since pg_usleep
2951 * isn't interruptible on some platforms.
2953 sigint_interrupt_enabled = true;
2954 for (i = 0; i < sleep; i++)
2956 pg_usleep(1000000L);
2960 sigint_interrupt_enabled = false;
2967 * a little code borrowed from PSQLexec() to manage ECHO_HIDDEN output.
2968 * returns true unless we have ECHO_HIDDEN_NOEXEC.
2971 lookup_function_echo_hidden(char * query)
2973 if (pset.echo_hidden != PSQL_ECHO_HIDDEN_OFF)
2975 printf(_("********* QUERY **********\n"
2977 "**************************\n\n"), query);
2981 fprintf(pset.logfile,
2982 _("********* QUERY **********\n"
2984 "**************************\n\n"), query);
2985 fflush(pset.logfile);
2988 if (pset.echo_hidden == PSQL_ECHO_HIDDEN_NOEXEC)
2995 * This function takes a function description, e.g. "x" or "x(int)", and
2996 * issues a query on the given connection to retrieve the function's OID
2997 * using a cast to regproc or regprocedure (as appropriate). The result,
2998 * if there is one, is returned at *foid. Note that we'll fail if the
2999 * function doesn't exist OR if there are multiple matching candidates
3000 * OR if there's something syntactically wrong with the function description;
3001 * unfortunately it can be hard to tell the difference.
3004 lookup_function_oid(const char *desc, Oid *foid)
3010 query = createPQExpBuffer();
3011 appendPQExpBufferStr(query, "SELECT ");
3012 appendStringLiteralConn(query, desc, pset.db);
3013 appendPQExpBuffer(query, "::pg_catalog.%s::pg_catalog.oid",
3014 strchr(desc, '(') ? "regprocedure" : "regproc");
3015 if (!lookup_function_echo_hidden(query->data))
3017 destroyPQExpBuffer(query);
3020 res = PQexec(pset.db, query->data);
3021 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
3022 *foid = atooid(PQgetvalue(res, 0, 0));
3025 minimal_error_message(res);
3030 destroyPQExpBuffer(query);
3036 * Fetches the "CREATE OR REPLACE FUNCTION ..." command that describes the
3037 * function with the given OID. If successful, the result is stored in buf.
3040 get_create_function_cmd(Oid oid, PQExpBuffer buf)
3046 query = createPQExpBuffer();
3047 printfPQExpBuffer(query, "SELECT pg_catalog.pg_get_functiondef(%u)", oid);
3049 if (!lookup_function_echo_hidden(query->data))
3051 destroyPQExpBuffer(query);
3054 res = PQexec(pset.db, query->data);
3055 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
3057 resetPQExpBuffer(buf);
3058 appendPQExpBufferStr(buf, PQgetvalue(res, 0, 0));
3062 minimal_error_message(res);
3067 destroyPQExpBuffer(query);
3073 * If the given argument of \ef ends with a line number, delete the line
3074 * number from the argument string and return it as an integer. (We need
3075 * this kluge because we're too lazy to parse \ef's function name argument
3076 * carefully --- we just slop it up in OT_WHOLE_LINE mode.)
3078 * Returns -1 if no line number is present, 0 on error, or a positive value
3082 strip_lineno_from_funcdesc(char *func)
3087 if (!func || func[0] == '\0')
3090 c = func + strlen(func) - 1;
3093 * This business of parsing backwards is dangerous as can be in a
3094 * multibyte environment: there is no reason to believe that we are
3095 * looking at the first byte of a character, nor are we necessarily
3096 * working in a "safe" encoding. Fortunately the bitpatterns we are
3097 * looking for are unlikely to occur as non-first bytes, but beware of
3098 * trying to expand the set of cases that can be recognized. We must
3099 * guard the <ctype.h> macros by using isascii() first, too.
3102 /* skip trailing whitespace */
3103 while (c > func && isascii((unsigned char) *c) && isspace((unsigned char) *c))
3106 /* must have a digit as last non-space char */
3107 if (c == func || !isascii((unsigned char) *c) || !isdigit((unsigned char) *c))
3110 /* find start of digit string */
3111 while (c > func && isascii((unsigned char) *c) && isdigit((unsigned char) *c))
3114 /* digits must be separated from func name by space or closing paren */
3115 /* notice also that we are not allowing an empty func name ... */
3116 if (c == func || !isascii((unsigned char) *c) ||
3117 !(isspace((unsigned char) *c) || *c == ')'))
3120 /* parse digit string */
3125 psql_error("invalid line number: %s\n", c);
3129 /* strip digit string from func */
3136 * Report just the primary error; this is to avoid cluttering the output
3137 * with, for instance, a redisplay of the internally generated query
3140 minimal_error_message(PGresult *res)
3145 msg = createPQExpBuffer();
3147 fld = PQresultErrorField(res, PG_DIAG_SEVERITY);
3149 printfPQExpBuffer(msg, "%s: ", fld);
3151 printfPQExpBuffer(msg, "ERROR: ");
3152 fld = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
3154 appendPQExpBufferStr(msg, fld);
3156 appendPQExpBufferStr(msg, "(not available)");
3157 appendPQExpBufferStr(msg, "\n");
3159 psql_error("%s", msg->data);
3161 destroyPQExpBuffer(msg);