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 */
20 #include <sys/types.h> /* for umask() */
21 #include <sys/stat.h> /* for stat() */
22 #include <fcntl.h> /* open() flags */
23 #include <unistd.h> /* for geteuid(), getpid(), stat() */
29 #include <sys/types.h> /* for umask() */
30 #include <sys/stat.h> /* for stat() */
33 #include <openssl/ssl.h>
36 #include "portability/instr_time.h"
39 #include "pqexpbuffer.h"
40 #include "dumputils.h"
47 #include "large_obj.h"
52 #include "variables.h"
55 /* functions for use in this file */
56 static backslashResult exec_command(const char *cmd,
57 PsqlScanState scan_state,
58 PQExpBuffer query_buf);
59 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
60 int lineno, bool *edited);
61 static bool do_connect(char *dbname, char *user, char *host, char *port);
62 static bool do_shell(const char *command);
63 static bool lookup_function_oid(PGconn *conn, const char *desc, Oid *foid);
64 static bool get_create_function_cmd(PGconn *conn, Oid oid, PQExpBuffer buf);
65 static int strip_lineno_from_funcdesc(char *func);
66 static void minimal_error_message(PGresult *res);
68 static void printSSLInfo(void);
71 static void checkWin32Codepage(void);
79 * Handles all the different commands that start with '\'.
80 * Ordinarily called by MainLoop().
82 * scan_state is a lexer working state that is set to continue scanning
83 * just after the '\'. The lexer is advanced past the command and all
84 * arguments on return.
86 * 'query_buf' contains the query-so-far, which may be modified by
87 * execution of the backslash command (for example, \r clears it).
88 * query_buf can be NULL if there is no query so far.
90 * Returns a status code indicating what action is desired, see command.h.
95 HandleSlashCmds(PsqlScanState scan_state,
96 PQExpBuffer query_buf)
98 backslashResult status = PSQL_CMD_SKIP_LINE;
102 Assert(scan_state != NULL);
104 /* Parse off the command name */
105 cmd = psql_scan_slash_command(scan_state);
107 /* And try to execute it */
108 status = exec_command(cmd, scan_state, query_buf);
110 if (status == PSQL_CMD_UNKNOWN)
112 if (pset.cur_cmd_interactive)
113 psql_error("Invalid command \\%s. Try \\? for help.\n", cmd);
115 psql_error("invalid command \\%s\n", cmd);
116 status = PSQL_CMD_ERROR;
119 if (status != PSQL_CMD_ERROR)
121 /* eat any remaining arguments after a valid command */
122 /* note we suppress evaluation of backticks here */
123 while ((arg = psql_scan_slash_option(scan_state,
124 OT_NO_EVAL, NULL, false)))
126 psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
132 /* silently throw away rest of line after an erroneous command */
133 while ((arg = psql_scan_slash_option(scan_state,
134 OT_WHOLE_LINE, NULL, false)))
138 /* if there is a trailing \\, swallow it */
139 psql_scan_slash_command_end(scan_state);
143 /* some commands write to queryFout, so make sure output is sent */
144 fflush(pset.queryFout);
150 * Read and interpret an argument to the \connect slash command.
153 read_connect_arg(PsqlScanState scan_state)
159 * Ideally we should treat the arguments as SQL identifiers. But for
160 * backwards compatibility with 7.2 and older pg_dump files, we have to
161 * take unquoted arguments verbatim (don't downcase them). For now,
162 * double-quoted arguments may be stripped of double quotes (as if SQL
163 * identifiers). By 7.4 or so, pg_dump files can be expected to
164 * double-quote all mixed-case \connect arguments, and then we can get rid
167 result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, "e, true);
175 if (*result == '\0' || strcmp(result, "-") == 0)
183 * Subroutine to actually try to execute a backslash command.
185 static backslashResult
186 exec_command(const char *cmd,
187 PsqlScanState scan_state,
188 PQExpBuffer query_buf)
190 bool success = true; /* indicate here if the command ran ok or
192 backslashResult status = PSQL_CMD_SKIP_LINE;
195 * \a -- toggle field alignment This makes little sense but we keep it
198 if (strcmp(cmd, "a") == 0)
200 if (pset.popt.topt.format != PRINT_ALIGNED)
201 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
203 success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
206 /* \C -- override table title (formerly change HTML caption) */
207 else if (strcmp(cmd, "C") == 0)
209 char *opt = psql_scan_slash_option(scan_state,
210 OT_NORMAL, NULL, true);
212 success = do_pset("title", opt, &pset.popt, pset.quiet);
217 * \c or \connect -- connect to database using the specified parameters.
219 * \c dbname user host port
221 * If any of these parameters are omitted or specified as '-', the current
222 * value of the parameter will be used instead. If the parameter has no
223 * current value, the default value for that parameter will be used. Some
226 * \c - - hst Connect to current database on current port of host
227 * "hst" as current user. \c - usr - prt Connect to current database on
228 * "prt" port of current host as user "usr". \c dbs Connect to
229 * "dbs" database on current port of current host as current user.
231 else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
238 opt1 = read_connect_arg(scan_state);
239 opt2 = read_connect_arg(scan_state);
240 opt3 = read_connect_arg(scan_state);
241 opt4 = read_connect_arg(scan_state);
243 success = do_connect(opt1, opt2, opt3, opt4);
252 else if (strcmp(cmd, "cd") == 0)
254 char *opt = psql_scan_slash_option(scan_state,
255 OT_NORMAL, NULL, true);
265 pw = getpwuid(geteuid());
268 psql_error("could not get home directory: %s\n", strerror(errno));
275 * On Windows, 'cd' without arguments prints the current
276 * directory, so if someone wants to code this here instead...
282 if (chdir(dir) == -1)
284 psql_error("\\%s: could not change directory to \"%s\": %s\n",
285 cmd, dir, strerror(errno));
291 pset.dirname = pg_strdup(dir);
292 canonicalize_path(pset.dirname);
298 /* \conninfo -- display information about the current connection */
299 else if (strcmp(cmd, "conninfo") == 0)
301 char *db = PQdb(pset.db);
302 char *host = PQhost(pset.db);
305 printf(_("You are currently not connected to a database.\n"));
309 host = DEFAULT_PGSOCKET_DIR;
310 /* If the host is an absolute path, the connection is via socket */
311 if (is_absolute_path(host))
312 printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
313 db, PQuser(pset.db), host, PQport(pset.db));
315 printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
316 db, PQuser(pset.db), host, PQport(pset.db));
322 else if (pg_strcasecmp(cmd, "copy") == 0)
324 char *opt = psql_scan_slash_option(scan_state,
325 OT_WHOLE_LINE, NULL, false);
327 success = do_copy(opt);
332 else if (strcmp(cmd, "copyright") == 0)
336 else if (cmd[0] == 'd')
342 /* We don't do SQLID reduction on the pattern yet */
343 pattern = psql_scan_slash_option(scan_state,
344 OT_NORMAL, NULL, true);
346 show_verbose = strchr(cmd, '+') ? true : false;
347 show_system = strchr(cmd, 'S') ? true : false;
355 success = describeTableDetails(pattern, show_verbose, show_system);
357 /* standard listing of interesting things */
358 success = listTables("tvsE", NULL, show_verbose, show_system);
361 success = describeAggregates(pattern, show_verbose, show_system);
364 success = describeTablespaces(pattern, show_verbose);
367 success = listConversions(pattern, show_verbose, show_system);
370 success = listCasts(pattern, show_verbose);
373 if (strncmp(cmd, "ddp", 3) == 0)
374 success = listDefaultACLs(pattern);
376 success = objectDescription(pattern, show_system);
379 success = listDomains(pattern, show_verbose, show_system);
381 case 'f': /* function subsystem */
391 success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
394 status = PSQL_CMD_UNKNOWN;
399 /* no longer distinct from \du */
400 success = describeRoles(pattern, show_verbose);
403 success = do_lo_list();
406 success = listLanguages(pattern, show_verbose, show_system);
409 success = listSchemas(pattern, show_verbose, show_system);
412 success = describeOperators(pattern, show_system);
415 success = listCollations(pattern, show_verbose, show_system);
418 success = permissionsList(pattern);
421 success = describeTypes(pattern, show_verbose, show_system);
428 success = listTables(&cmd[1], pattern, show_verbose, show_system);
431 if (cmd[2] == 'd' && cmd[3] == 's')
433 char *pattern2 = NULL;
436 pattern2 = psql_scan_slash_option(scan_state,
437 OT_NORMAL, NULL, true);
438 success = listDbRoleSettings(pattern, pattern2);
441 success = PSQL_CMD_UNKNOWN;
444 success = describeRoles(pattern, show_verbose);
446 case 'F': /* text search subsystem */
451 success = listTSConfigs(pattern, show_verbose);
454 success = listTSParsers(pattern, show_verbose);
457 success = listTSDictionaries(pattern, show_verbose);
460 success = listTSTemplates(pattern, show_verbose);
463 status = PSQL_CMD_UNKNOWN;
467 case 'e': /* SQL/MED subsystem */
471 success = listForeignServers(pattern, show_verbose);
474 success = listUserMappings(pattern, show_verbose);
477 success = listForeignDataWrappers(pattern, show_verbose);
480 success = listForeignTables(pattern, show_verbose);
483 status = PSQL_CMD_UNKNOWN;
487 case 'x': /* Extensions */
489 success = listExtensionContents(pattern);
491 success = listExtensions(pattern);
493 case 'y': /* Event Triggers */
494 success = listEventTriggers(pattern, show_verbose);
497 status = PSQL_CMD_UNKNOWN;
506 * \e or \edit -- edit the current query buffer, or edit a file and make
507 * it the query buffer
509 else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
513 psql_error("no query buffer\n");
514 status = PSQL_CMD_ERROR;
522 fname = psql_scan_slash_option(scan_state,
523 OT_NORMAL, NULL, true);
526 /* try to get separate lineno arg */
527 ln = psql_scan_slash_option(scan_state,
528 OT_NORMAL, NULL, true);
531 /* only one arg; maybe it is lineno not fname */
533 strspn(fname, "0123456789") == strlen(fname))
535 /* all digits, so assume it is lineno */
546 psql_error("invalid line number: %s\n", ln);
547 status = PSQL_CMD_ERROR;
550 if (status != PSQL_CMD_ERROR)
552 expand_tilde(&fname);
554 canonicalize_path(fname);
555 if (do_edit(fname, query_buf, lineno, NULL))
556 status = PSQL_CMD_NEWEDIT;
558 status = PSQL_CMD_ERROR;
568 * \ef -- edit the named function, or present a blank CREATE FUNCTION
569 * template if no argument is given
571 else if (strcmp(cmd, "ef") == 0)
575 if (pset.sversion < 80400)
577 psql_error("The server (version %d.%d) does not support editing function source.\n",
578 pset.sversion / 10000, (pset.sversion / 100) % 100);
579 status = PSQL_CMD_ERROR;
583 psql_error("no query buffer\n");
584 status = PSQL_CMD_ERROR;
589 Oid foid = InvalidOid;
591 func = psql_scan_slash_option(scan_state,
592 OT_WHOLE_LINE, NULL, true);
593 lineno = strip_lineno_from_funcdesc(func);
596 /* error already reported */
597 status = PSQL_CMD_ERROR;
601 /* set up an empty command to fill in */
602 printfPQExpBuffer(query_buf,
603 "CREATE FUNCTION ( )\n"
606 " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
610 else if (!lookup_function_oid(pset.db, func, &foid))
612 /* error already reported */
613 status = PSQL_CMD_ERROR;
615 else if (!get_create_function_cmd(pset.db, foid, query_buf))
617 /* error already reported */
618 status = PSQL_CMD_ERROR;
623 * lineno "1" should correspond to the first line of the
624 * function body. We expect that pg_get_functiondef() will
625 * emit that on a line beginning with "AS ", and that there
626 * can be no such line before the real start of the function
627 * body. Increment lineno by the number of lines before that
628 * line, so that it becomes relative to the first line of the
629 * function definition.
631 const char *lines = query_buf->data;
633 while (*lines != '\0')
635 if (strncmp(lines, "AS ", 3) == 0)
638 /* find start of next line */
639 lines = strchr(lines, '\n');
650 if (status != PSQL_CMD_ERROR)
654 if (!do_edit(NULL, query_buf, lineno, &edited))
655 status = PSQL_CMD_ERROR;
657 puts(_("No changes"));
659 status = PSQL_CMD_NEWEDIT;
663 /* \echo and \qecho */
664 else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
668 bool no_newline = false;
672 if (strcmp(cmd, "qecho") == 0)
673 fout = pset.queryFout;
677 while ((value = psql_scan_slash_option(scan_state,
678 OT_NORMAL, "ed, false)))
680 if (!quoted && strcmp(value, "-n") == 0)
696 /* \encoding -- set/show client side encoding */
697 else if (strcmp(cmd, "encoding") == 0)
699 char *encoding = psql_scan_slash_option(scan_state,
700 OT_NORMAL, NULL, false);
705 puts(pg_encoding_to_char(pset.encoding));
710 if (PQsetClientEncoding(pset.db, encoding) == -1)
711 psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
714 /* save encoding info into psql internal data */
715 pset.encoding = PQclientEncoding(pset.db);
716 pset.popt.topt.encoding = pset.encoding;
717 SetVariable(pset.vars, "ENCODING",
718 pg_encoding_to_char(pset.encoding));
724 /* \f -- change field separator */
725 else if (strcmp(cmd, "f") == 0)
727 char *fname = psql_scan_slash_option(scan_state,
728 OT_NORMAL, NULL, false);
730 success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
734 /* \g [filename] -- send query, optionally with output to file/pipe */
735 else if (strcmp(cmd, "g") == 0)
737 char *fname = psql_scan_slash_option(scan_state,
738 OT_FILEPIPE, NULL, false);
744 expand_tilde(&fname);
745 pset.gfname = pg_strdup(fname);
748 status = PSQL_CMD_SEND;
751 /* \gset [prefix] -- send query and store result into variables */
752 else if (strcmp(cmd, "gset") == 0)
754 char *prefix = psql_scan_slash_option(scan_state,
755 OT_NORMAL, NULL, false);
758 pset.gset_prefix = prefix;
761 /* we must set a non-NULL prefix to trigger storing */
762 pset.gset_prefix = pg_strdup("");
764 status = PSQL_CMD_SEND;
768 else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
770 char *opt = psql_scan_slash_option(scan_state,
771 OT_WHOLE_LINE, NULL, false);
774 /* strip any trailing spaces and semicolons */
779 (isspace((unsigned char) opt[len - 1])
780 || opt[len - 1] == ';'))
784 helpSQL(opt, pset.popt.topt.pager);
789 else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
791 if (pset.popt.topt.format != PRINT_HTML)
792 success = do_pset("format", "html", &pset.popt, pset.quiet);
794 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
798 /* \i and \ir include files */
799 else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0
800 || strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
802 char *fname = psql_scan_slash_option(scan_state,
803 OT_NORMAL, NULL, true);
807 psql_error("\\%s: missing required argument\n", cmd);
812 bool include_relative;
814 include_relative = (strcmp(cmd, "ir") == 0
815 || strcmp(cmd, "include_relative") == 0);
816 expand_tilde(&fname);
817 success = (process_file(fname, false, include_relative) == EXIT_SUCCESS);
822 /* \l is list databases */
823 else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0)
824 success = listAllDbs(false);
825 else if (strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
826 success = listAllDbs(true);
829 * large object things
831 else if (strncmp(cmd, "lo_", 3) == 0)
836 opt1 = psql_scan_slash_option(scan_state,
837 OT_NORMAL, NULL, true);
838 opt2 = psql_scan_slash_option(scan_state,
839 OT_NORMAL, NULL, true);
841 if (strcmp(cmd + 3, "export") == 0)
845 psql_error("\\%s: missing required argument\n", cmd);
851 success = do_lo_export(opt1, opt2);
855 else if (strcmp(cmd + 3, "import") == 0)
859 psql_error("\\%s: missing required argument\n", cmd);
865 success = do_lo_import(opt1, opt2);
869 else if (strcmp(cmd + 3, "list") == 0)
870 success = do_lo_list();
872 else if (strcmp(cmd + 3, "unlink") == 0)
876 psql_error("\\%s: missing required argument\n", cmd);
880 success = do_lo_unlink(opt1);
884 status = PSQL_CMD_UNKNOWN;
891 /* \o -- set query output */
892 else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
894 char *fname = psql_scan_slash_option(scan_state,
895 OT_FILEPIPE, NULL, true);
897 expand_tilde(&fname);
898 success = setQFout(fname);
902 /* \p prints the current query buffer */
903 else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
905 if (query_buf && query_buf->len > 0)
906 puts(query_buf->data);
907 else if (!pset.quiet)
908 puts(_("Query buffer is empty."));
912 /* \password -- set user password */
913 else if (strcmp(cmd, "password") == 0)
918 pw1 = simple_prompt("Enter new password: ", 100, false);
919 pw2 = simple_prompt("Enter it again: ", 100, false);
921 if (strcmp(pw1, pw2) != 0)
923 psql_error("Passwords didn't match.\n");
928 char *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true);
930 char *encrypted_password;
935 user = PQuser(pset.db);
937 encrypted_password = PQencryptPassword(pw1, user);
939 if (!encrypted_password)
941 psql_error("Password encryption failed.\n");
949 initPQExpBuffer(&buf);
950 printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
952 appendStringLiteralConn(&buf, encrypted_password, pset.db);
953 res = PSQLexec(buf.data, false);
954 termPQExpBuffer(&buf);
959 PQfreemem(encrypted_password);
970 /* \prompt -- prompt and set variable */
971 else if (strcmp(cmd, "prompt") == 0)
978 arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
979 arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
983 psql_error("\\%s: missing required argument\n", cmd);
999 result = simple_prompt(prompt_text, 4096, true);
1004 fputs(prompt_text, stdout);
1007 result = gets_fromFile(stdin);
1010 if (!SetVariable(pset.vars, opt, result))
1012 psql_error("\\%s: error while setting variable\n", cmd);
1023 /* \pset -- set printing parameters */
1024 else if (strcmp(cmd, "pset") == 0)
1026 char *opt0 = psql_scan_slash_option(scan_state,
1027 OT_NORMAL, NULL, false);
1028 char *opt1 = psql_scan_slash_option(scan_state,
1029 OT_NORMAL, NULL, false);
1033 psql_error("\\%s: missing required argument\n", cmd);
1037 success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
1044 else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
1045 status = PSQL_CMD_TERMINATE;
1047 /* reset(clear) the buffer */
1048 else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
1050 resetPQExpBuffer(query_buf);
1051 psql_scan_reset(scan_state);
1053 puts(_("Query buffer reset (cleared)."));
1056 /* \s save history in a file or show it on the screen */
1057 else if (strcmp(cmd, "s") == 0)
1059 char *fname = psql_scan_slash_option(scan_state,
1060 OT_NORMAL, NULL, true);
1062 #if defined(WIN32) && !defined(__CYGWIN__)
1065 * XXX This does not work for all terminal environments or for output
1066 * containing non-ASCII characters; see comments in simple_prompt().
1068 #define DEVTTY "con"
1070 #define DEVTTY "/dev/tty"
1073 expand_tilde(&fname);
1074 /* This scrolls off the screen when using /dev/tty */
1075 success = saveHistory(fname ? fname : DEVTTY, -1, false, false);
1076 if (success && !pset.quiet && fname)
1077 printf(gettext("Wrote history to file \"%s/%s\".\n"),
1078 pset.dirname ? pset.dirname : ".", fname);
1084 /* \set -- generalized set variable/option command */
1085 else if (strcmp(cmd, "set") == 0)
1087 char *opt0 = psql_scan_slash_option(scan_state,
1088 OT_NORMAL, NULL, false);
1092 /* list all variables */
1093 PrintVariables(pset.vars);
1099 * Set variable to the concatenation of the arguments.
1104 opt = psql_scan_slash_option(scan_state,
1105 OT_NORMAL, NULL, false);
1106 newval = pg_strdup(opt ? opt : "");
1109 while ((opt = psql_scan_slash_option(scan_state,
1110 OT_NORMAL, NULL, false)))
1112 newval = realloc(newval, strlen(newval) + strlen(opt) + 1);
1115 psql_error("out of memory\n");
1118 strcat(newval, opt);
1122 if (!SetVariable(pset.vars, opt0, newval))
1124 psql_error("\\%s: error while setting variable\n", cmd);
1133 /* \setenv -- set environment command */
1134 else if (strcmp(cmd, "setenv") == 0)
1136 char *envvar = psql_scan_slash_option(scan_state,
1137 OT_NORMAL, NULL, false);
1138 char *envval = psql_scan_slash_option(scan_state,
1139 OT_NORMAL, NULL, false);
1143 psql_error("\\%s: missing required argument\n", cmd);
1146 else if (strchr(envvar, '=') != NULL)
1148 psql_error("\\%s: environment variable name must not contain \"=\"\n",
1154 /* No argument - unset the environment variable */
1160 /* Set variable to the value of the next argument */
1161 int len = strlen(envvar) + strlen(envval) + 1;
1162 char *newval = pg_malloc(len + 1);
1164 snprintf(newval, len + 1, "%s=%s", envvar, envval);
1169 * Do not free newval here, it will screw up the environment if
1170 * you do. See putenv man page for details. That means we leak a
1171 * bit of memory here, but not enough to worry about.
1178 /* \sf -- show a function's source code */
1179 else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
1181 bool show_linenumbers = (strcmp(cmd, "sf+") == 0);
1182 PQExpBuffer func_buf;
1184 Oid foid = InvalidOid;
1186 func_buf = createPQExpBuffer();
1187 func = psql_scan_slash_option(scan_state,
1188 OT_WHOLE_LINE, NULL, true);
1189 if (pset.sversion < 80400)
1191 psql_error("The server (version %d.%d) does not support showing function source.\n",
1192 pset.sversion / 10000, (pset.sversion / 100) % 100);
1193 status = PSQL_CMD_ERROR;
1197 psql_error("function name is required\n");
1198 status = PSQL_CMD_ERROR;
1200 else if (!lookup_function_oid(pset.db, func, &foid))
1202 /* error already reported */
1203 status = PSQL_CMD_ERROR;
1205 else if (!get_create_function_cmd(pset.db, foid, func_buf))
1207 /* error already reported */
1208 status = PSQL_CMD_ERROR;
1215 /* Select output stream: stdout, pager, or file */
1216 if (pset.queryFout == stdout)
1218 /* count lines in function to see if pager is needed */
1220 const char *lines = func_buf->data;
1222 while (*lines != '\0')
1225 /* find start of next line */
1226 lines = strchr(lines, '\n');
1232 output = PageOutput(lineno, pset.popt.topt.pager);
1237 /* use previously set output file, without pager */
1238 output = pset.queryFout;
1242 if (show_linenumbers)
1244 bool in_header = true;
1246 char *lines = func_buf->data;
1249 * lineno "1" should correspond to the first line of the
1250 * function body. We expect that pg_get_functiondef() will
1251 * emit that on a line beginning with "AS ", and that there
1252 * can be no such line before the real start of the function
1255 * Note that this loop scribbles on func_buf.
1257 while (*lines != '\0')
1261 if (in_header && strncmp(lines, "AS ", 3) == 0)
1263 /* increment lineno only for body's lines */
1267 /* find and mark end of current line */
1268 eol = strchr(lines, '\n');
1272 /* show current line as appropriate */
1274 fprintf(output, " %s\n", lines);
1276 fprintf(output, "%-7d %s\n", lineno, lines);
1278 /* advance to next line, if any */
1286 /* just send the function definition to output */
1287 fputs(func_buf->data, output);
1296 destroyPQExpBuffer(func_buf);
1299 /* \t -- turn off headers and row count */
1300 else if (strcmp(cmd, "t") == 0)
1302 char *opt = psql_scan_slash_option(scan_state,
1303 OT_NORMAL, NULL, true);
1305 success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
1309 /* \T -- define html <table ...> attributes */
1310 else if (strcmp(cmd, "T") == 0)
1312 char *value = psql_scan_slash_option(scan_state,
1313 OT_NORMAL, NULL, false);
1315 success = do_pset("tableattr", value, &pset.popt, pset.quiet);
1319 /* \timing -- toggle timing of queries */
1320 else if (strcmp(cmd, "timing") == 0)
1322 char *opt = psql_scan_slash_option(scan_state,
1323 OT_NORMAL, NULL, false);
1326 pset.timing = ParseVariableBool(opt);
1328 pset.timing = !pset.timing;
1332 puts(_("Timing is on."));
1334 puts(_("Timing is off."));
1340 else if (strcmp(cmd, "unset") == 0)
1342 char *opt = psql_scan_slash_option(scan_state,
1343 OT_NORMAL, NULL, false);
1347 psql_error("\\%s: missing required argument\n", cmd);
1350 else if (!SetVariable(pset.vars, opt, NULL))
1352 psql_error("\\%s: error while setting variable\n", cmd);
1358 /* \w -- write query buffer to file */
1359 else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
1362 bool is_pipe = false;
1367 psql_error("no query buffer\n");
1368 status = PSQL_CMD_ERROR;
1372 fname = psql_scan_slash_option(scan_state,
1373 OT_FILEPIPE, NULL, true);
1374 expand_tilde(&fname);
1378 psql_error("\\%s: missing required argument\n", cmd);
1383 if (fname[0] == '|')
1386 fd = popen(&fname[1], "w");
1390 canonicalize_path(fname);
1391 fd = fopen(fname, "w");
1395 psql_error("%s: %s\n", fname, strerror(errno));
1405 if (query_buf && query_buf->len > 0)
1406 fprintf(fd, "%s\n", query_buf->data);
1409 result = pclose(fd);
1411 result = fclose(fd);
1415 psql_error("%s: %s\n", fname, strerror(errno));
1423 /* \x -- set or toggle expanded table representation */
1424 else if (strcmp(cmd, "x") == 0)
1426 char *opt = psql_scan_slash_option(scan_state,
1427 OT_NORMAL, NULL, true);
1429 success = do_pset("expanded", opt, &pset.popt, pset.quiet);
1433 /* \z -- list table rights (equivalent to \dp) */
1434 else if (strcmp(cmd, "z") == 0)
1436 char *pattern = psql_scan_slash_option(scan_state,
1437 OT_NORMAL, NULL, true);
1439 success = permissionsList(pattern);
1444 /* \! -- shell escape */
1445 else if (strcmp(cmd, "!") == 0)
1447 char *opt = psql_scan_slash_option(scan_state,
1448 OT_WHOLE_LINE, NULL, false);
1450 success = do_shell(opt);
1454 /* \? -- slash command help */
1455 else if (strcmp(cmd, "?") == 0)
1456 slashUsage(pset.popt.topt.pager);
1461 * These commands don't do anything. I just use them to test the parser.
1463 else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
1468 while ((value = psql_scan_slash_option(scan_state,
1469 OT_NORMAL, NULL, true)))
1471 psql_error("+ opt(%d) = |%s|\n", i++, value);
1478 status = PSQL_CMD_UNKNOWN;
1481 status = PSQL_CMD_ERROR;
1487 * Ask the user for a password; 'username' is the username the
1488 * password is for, if one has been explicitly specified. Returns a
1492 prompt_for_password(const char *username)
1496 if (username == NULL)
1497 result = simple_prompt("Password: ", 100, false);
1502 prompt_text = pg_malloc(strlen(username) + 100);
1503 snprintf(prompt_text, strlen(username) + 100,
1504 _("Password for user %s: "), username);
1505 result = simple_prompt(prompt_text, 100, false);
1513 param_is_newly_set(const char *old_val, const char *new_val)
1515 if (new_val == NULL)
1518 if (old_val == NULL || strcmp(old_val, new_val) != 0)
1525 * do_connect -- handler for \connect
1527 * Connects to a database with given parameters. If there exists an
1528 * established connection, NULL values will be replaced with the ones
1529 * in the current connection. Otherwise NULL will be passed for that
1530 * parameter to PQconnectdbParams(), so the libpq defaults will be used.
1532 * In interactive mode, if connection fails with the given parameters,
1533 * the old connection will be kept.
1536 do_connect(char *dbname, char *user, char *host, char *port)
1538 PGconn *o_conn = pset.db,
1540 char *password = NULL;
1542 if (!o_conn && (!dbname || !user || !host || !port))
1545 * We don't know the supplied connection parameters and don't want
1546 * to connect to the wrong database by using defaults, so require
1547 * all parameters to be specified.
1549 psql_error("All connection parameters must be supplied because no "
1550 "database connection exists\n");
1555 dbname = PQdb(o_conn);
1557 user = PQuser(o_conn);
1559 host = PQhost(o_conn);
1561 port = PQport(o_conn);
1564 * If the user asked to be prompted for a password, ask for one now. If
1565 * not, use the password from the old connection, provided the username
1566 * has not changed. Otherwise, try to connect without a password first,
1567 * and then ask for a password if needed.
1569 * XXX: this behavior leads to spurious connection attempts recorded in
1570 * the postmaster's log. But libpq offers no API that would let us obtain
1571 * a password and then continue with the first connection attempt.
1573 if (pset.getPassword == TRI_YES)
1575 password = prompt_for_password(user);
1577 else if (o_conn && user && strcmp(PQuser(o_conn), user) == 0)
1579 password = pg_strdup(PQpass(o_conn));
1584 #define PARAMS_ARRAY_SIZE 8
1585 const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
1586 const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
1588 keywords[0] = "host";
1590 keywords[1] = "port";
1592 keywords[2] = "user";
1594 keywords[3] = "password";
1595 values[3] = password;
1596 keywords[4] = "dbname";
1598 keywords[5] = "fallback_application_name";
1599 values[5] = pset.progname;
1600 keywords[6] = "client_encoding";
1601 values[6] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto";
1605 n_conn = PQconnectdbParams(keywords, values, true);
1610 /* We can immediately discard the password -- no longer needed */
1614 if (PQstatus(n_conn) == CONNECTION_OK)
1618 * Connection attempt failed; either retry the connection attempt with
1619 * a new password, or give up.
1621 if (!password && PQconnectionNeedsPassword(n_conn) && pset.getPassword != TRI_NO)
1624 password = prompt_for_password(user);
1629 * Failed to connect to the database. In interactive mode, keep the
1630 * previous connection to the DB; in scripting mode, close our
1631 * previous connection as well.
1633 if (pset.cur_cmd_interactive)
1635 psql_error("%s", PQerrorMessage(n_conn));
1637 /* pset.db is left unmodified */
1639 psql_error("Previous connection kept\n");
1643 psql_error("\\connect: %s", PQerrorMessage(n_conn));
1656 * Replace the old connection with the new one, and update
1657 * connection-dependent variables.
1659 PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
1662 connection_warnings(false); /* Must be after SyncVariables */
1664 /* Tell the user about the new connection */
1667 if (param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) ||
1668 param_is_newly_set(PQport(o_conn), PQport(pset.db)))
1670 char *host = PQhost(pset.db);
1673 host = DEFAULT_PGSOCKET_DIR;
1674 /* If the host is an absolute path, the connection is via socket */
1675 if (is_absolute_path(host))
1676 printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
1677 PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
1679 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
1680 PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
1683 printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
1684 PQdb(pset.db), PQuser(pset.db));
1694 connection_warnings(bool in_startup)
1696 if (!pset.quiet && !pset.notty)
1698 int client_ver = parse_version(PG_VERSION);
1700 if (pset.sversion != client_ver)
1702 const char *server_version;
1703 char server_ver_str[16];
1705 /* Try to get full text form, might include "devel" etc */
1706 server_version = PQparameterStatus(pset.db, "server_version");
1707 if (!server_version)
1709 snprintf(server_ver_str, sizeof(server_ver_str),
1711 pset.sversion / 10000,
1712 (pset.sversion / 100) % 100,
1713 pset.sversion % 100);
1714 server_version = server_ver_str;
1717 printf(_("%s (%s, server %s)\n"),
1718 pset.progname, PG_VERSION, server_version);
1720 /* For version match, only print psql banner on startup. */
1721 else if (in_startup)
1722 printf("%s (%s)\n", pset.progname, PG_VERSION);
1724 if (pset.sversion / 100 > client_ver / 100)
1725 printf(_("WARNING: %s major version %d.%d, server major version %d.%d.\n"
1726 " Some psql features might not work.\n"),
1727 pset.progname, client_ver / 10000, (client_ver / 100) % 100,
1728 pset.sversion / 10000, (pset.sversion / 100) % 100);
1731 checkWin32Codepage();
1741 * Prints information about the current SSL connection, if SSL is in use
1750 ssl = PQgetssl(pset.db);
1752 return; /* no SSL */
1754 SSL_get_cipher_bits(ssl, &sslbits);
1755 printf(_("SSL connection (cipher: %s, bits: %d)\n"),
1756 SSL_get_cipher(ssl), sslbits);
1760 * If psql is compiled without SSL but is using a libpq with SSL, we
1761 * cannot figure out the specifics about the connection. But we know it's
1764 if (PQgetssl(pset.db))
1765 printf(_("SSL connection (unknown cipher)\n"));
1771 * checkWin32Codepage
1773 * Prints a warning when win32 console codepage differs from Windows codepage
1777 checkWin32Codepage(void)
1783 concp = GetConsoleCP();
1786 printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
1787 " 8-bit characters might not work correctly. See psql reference\n"
1788 " page \"Notes for Windows users\" for details.\n"),
1798 * Make psql's internal variables agree with connection state upon
1799 * establishing a new connection.
1804 /* get stuff from connection */
1805 pset.encoding = PQclientEncoding(pset.db);
1806 pset.popt.topt.encoding = pset.encoding;
1807 pset.sversion = PQserverVersion(pset.db);
1809 SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
1810 SetVariable(pset.vars, "USER", PQuser(pset.db));
1811 SetVariable(pset.vars, "HOST", PQhost(pset.db));
1812 SetVariable(pset.vars, "PORT", PQport(pset.db));
1813 SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
1815 /* send stuff to it, too */
1816 PQsetErrorVerbosity(pset.db, pset.verbosity);
1822 * Clear variables that should be not be set when there is no connection.
1825 UnsyncVariables(void)
1827 SetVariable(pset.vars, "DBNAME", NULL);
1828 SetVariable(pset.vars, "USER", NULL);
1829 SetVariable(pset.vars, "HOST", NULL);
1830 SetVariable(pset.vars, "PORT", NULL);
1831 SetVariable(pset.vars, "ENCODING", NULL);
1836 * do_edit -- handler for \e
1838 * If you do not specify a filename, the current query buffer will be copied
1839 * into a temporary one.
1842 editFile(const char *fname, int lineno)
1844 const char *editorName;
1845 const char *editor_lineno_arg = NULL;
1849 Assert(fname != NULL);
1851 /* Find an editor to use */
1852 editorName = getenv("PSQL_EDITOR");
1854 editorName = getenv("EDITOR");
1856 editorName = getenv("VISUAL");
1858 editorName = DEFAULT_EDITOR;
1860 /* Get line number argument, if we need it. */
1863 editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
1864 #ifdef DEFAULT_EDITOR_LINENUMBER_ARG
1865 if (!editor_lineno_arg)
1866 editor_lineno_arg = DEFAULT_EDITOR_LINENUMBER_ARG;
1868 if (!editor_lineno_arg)
1870 psql_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n");
1875 /* Allocate sufficient memory for command line. */
1877 sys = pg_malloc(strlen(editorName)
1878 + strlen(editor_lineno_arg) + 10 /* for integer */
1879 + 1 + strlen(fname) + 10 + 1);
1881 sys = pg_malloc(strlen(editorName) + strlen(fname) + 10 + 1);
1884 * On Unix the EDITOR value should *not* be quoted, since it might include
1885 * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
1886 * if necessary. But this policy is not very workable on Windows, due to
1887 * severe brain damage in their command shell plus the fact that standard
1888 * program paths include spaces.
1892 sprintf(sys, "exec %s %s%d '%s'",
1893 editorName, editor_lineno_arg, lineno, fname);
1895 sprintf(sys, "exec %s '%s'",
1899 sprintf(sys, SYSTEMQUOTE "\"%s\" %s%d \"%s\"" SYSTEMQUOTE,
1900 editorName, editor_lineno_arg, lineno, fname);
1902 sprintf(sys, SYSTEMQUOTE "\"%s\" \"%s\"" SYSTEMQUOTE,
1905 result = system(sys);
1907 psql_error("could not start editor \"%s\"\n", editorName);
1908 else if (result == 127)
1909 psql_error("could not start /bin/sh\n");
1918 do_edit(const char *filename_arg, PQExpBuffer query_buf,
1919 int lineno, bool *edited)
1921 char fnametmp[MAXPGPATH];
1922 FILE *stream = NULL;
1931 fname = filename_arg;
1934 /* make a temp file to edit */
1936 const char *tmpdir = getenv("TMPDIR");
1941 char tmpdir[MAXPGPATH];
1944 ret = GetTempPath(MAXPGPATH, tmpdir);
1945 if (ret == 0 || ret > MAXPGPATH)
1947 psql_error("could not locate temporary directory: %s\n",
1948 !ret ? strerror(errno) : "");
1953 * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
1954 * current directory to the supplied path unless we use only
1955 * backslashes, so we do that.
1959 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
1960 "/", (int) getpid());
1962 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
1963 "" /* trailing separator already present */ , (int) getpid());
1966 fname = (const char *) fnametmp;
1968 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
1970 stream = fdopen(fd, "w");
1972 if (fd == -1 || !stream)
1974 psql_error("could not open temporary file \"%s\": %s\n", fname, strerror(errno));
1979 unsigned int ql = query_buf->len;
1981 if (ql == 0 || query_buf->data[ql - 1] != '\n')
1983 appendPQExpBufferChar(query_buf, '\n');
1987 if (fwrite(query_buf->data, 1, ql, stream) != ql)
1989 psql_error("%s: %s\n", fname, strerror(errno));
1994 else if (fclose(stream) != 0)
1996 psql_error("%s: %s\n", fname, strerror(errno));
2003 if (!error && stat(fname, &before) != 0)
2005 psql_error("%s: %s\n", fname, strerror(errno));
2011 error = !editFile(fname, lineno);
2013 if (!error && stat(fname, &after) != 0)
2015 psql_error("%s: %s\n", fname, strerror(errno));
2019 if (!error && before.st_mtime != after.st_mtime)
2021 stream = fopen(fname, PG_BINARY_R);
2024 psql_error("%s: %s\n", fname, strerror(errno));
2029 /* read file back into query_buf */
2032 resetPQExpBuffer(query_buf);
2033 while (fgets(line, sizeof(line), stream) != NULL)
2034 appendPQExpBufferStr(query_buf, line);
2038 psql_error("%s: %s\n", fname, strerror(errno));
2050 /* remove temp file */
2053 if (remove(fname) == -1)
2055 psql_error("%s: %s\n", fname, strerror(errno));
2068 * Read commands from filename and then them to the main processing loop
2069 * Handler for \i and \ir, but can be used for other things as well. Returns
2070 * MainLoop() error code.
2072 * If use_relative_path is true and filename is not an absolute path, then open
2073 * the file from where the currently processed file (if any) is located.
2076 process_file(char *filename, bool single_txn, bool use_relative_path)
2081 char relpath[MAXPGPATH];
2089 else if (strcmp(filename, "-") != 0)
2091 canonicalize_path(filename);
2094 * If we were asked to resolve the pathname relative to the location
2095 * of the currently executing script, and there is one, and this is a
2096 * relative pathname, then prepend all but the last pathname component
2097 * of the current script to this pathname.
2099 if (use_relative_path && pset.inputfile &&
2100 !is_absolute_path(filename) && !has_drive_prefix(filename))
2102 strlcpy(relpath, pset.inputfile, sizeof(relpath));
2103 get_parent_directory(relpath);
2104 join_path_components(relpath, relpath, filename);
2105 canonicalize_path(relpath);
2110 fd = fopen(filename, PG_BINARY_R);
2114 psql_error("%s: %s\n", filename, strerror(errno));
2115 return EXIT_FAILURE;
2121 filename = "<stdin>"; /* for future error messages */
2124 oldfilename = pset.inputfile;
2125 pset.inputfile = filename;
2129 if ((res = PSQLexec("BEGIN", false)) == NULL)
2131 if (pset.on_error_stop)
2141 result = MainLoop(fd);
2145 if ((res = PSQLexec("COMMIT", false)) == NULL)
2147 if (pset.on_error_stop)
2161 pset.inputfile = oldfilename;
2172 _align2string(enum printFormat in)
2179 case PRINT_UNALIGNED:
2194 case PRINT_LATEX_LONGTABLE:
2195 return "latex-longtable";
2197 case PRINT_TROFF_MS:
2206 do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
2210 Assert(param != NULL);
2213 vallen = strlen(value);
2216 if (strcmp(param, "format") == 0)
2220 else if (pg_strncasecmp("unaligned", value, vallen) == 0)
2221 popt->topt.format = PRINT_UNALIGNED;
2222 else if (pg_strncasecmp("aligned", value, vallen) == 0)
2223 popt->topt.format = PRINT_ALIGNED;
2224 else if (pg_strncasecmp("wrapped", value, vallen) == 0)
2225 popt->topt.format = PRINT_WRAPPED;
2226 else if (pg_strncasecmp("html", value, vallen) == 0)
2227 popt->topt.format = PRINT_HTML;
2228 else if (pg_strncasecmp("latex", value, vallen) == 0)
2229 popt->topt.format = PRINT_LATEX;
2230 else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
2231 popt->topt.format = PRINT_LATEX_LONGTABLE;
2232 else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
2233 popt->topt.format = PRINT_TROFF_MS;
2236 psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, latex, troff-ms\n");
2241 printf(_("Output format is %s.\n"), _align2string(popt->topt.format));
2244 /* set table line style */
2245 else if (strcmp(param, "linestyle") == 0)
2249 else if (pg_strncasecmp("ascii", value, vallen) == 0)
2250 popt->topt.line_style = &pg_asciiformat;
2251 else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
2252 popt->topt.line_style = &pg_asciiformat_old;
2253 else if (pg_strncasecmp("unicode", value, vallen) == 0)
2254 popt->topt.line_style = &pg_utf8format;
2257 psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n");
2262 printf(_("Line style is %s.\n"),
2263 get_line_style(&popt->topt)->name);
2266 /* set border style/width */
2267 else if (strcmp(param, "border") == 0)
2270 popt->topt.border = atoi(value);
2273 printf(_("Border style is %d.\n"), popt->topt.border);
2276 /* set expanded/vertical mode */
2277 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
2279 if (value && pg_strcasecmp(value, "auto") == 0)
2280 popt->topt.expanded = 2;
2282 popt->topt.expanded = ParseVariableBool(value);
2284 popt->topt.expanded = !popt->topt.expanded;
2287 if (popt->topt.expanded == 1)
2288 printf(_("Expanded display is on.\n"));
2289 else if (popt->topt.expanded == 2)
2290 printf(_("Expanded display is used automatically.\n"));
2292 printf(_("Expanded display is off.\n"));
2296 /* locale-aware numeric output */
2297 else if (strcmp(param, "numericlocale") == 0)
2300 popt->topt.numericLocale = ParseVariableBool(value);
2302 popt->topt.numericLocale = !popt->topt.numericLocale;
2305 if (popt->topt.numericLocale)
2306 puts(_("Showing locale-adjusted numeric output."));
2308 puts(_("Locale-adjusted numeric output is off."));
2313 else if (strcmp(param, "null") == 0)
2317 free(popt->nullPrint);
2318 popt->nullPrint = pg_strdup(value);
2321 printf(_("Null display is \"%s\".\n"), popt->nullPrint ? popt->nullPrint : "");
2324 /* field separator for unaligned text */
2325 else if (strcmp(param, "fieldsep") == 0)
2329 free(popt->topt.fieldSep.separator);
2330 popt->topt.fieldSep.separator = pg_strdup(value);
2331 popt->topt.fieldSep.separator_zero = false;
2335 if (popt->topt.fieldSep.separator_zero)
2336 printf(_("Field separator is zero byte.\n"));
2338 printf(_("Field separator is \"%s\".\n"), popt->topt.fieldSep.separator);
2342 else if (strcmp(param, "fieldsep_zero") == 0)
2344 free(popt->topt.fieldSep.separator);
2345 popt->topt.fieldSep.separator = NULL;
2346 popt->topt.fieldSep.separator_zero = true;
2348 printf(_("Field separator is zero byte.\n"));
2351 /* record separator for unaligned text */
2352 else if (strcmp(param, "recordsep") == 0)
2356 free(popt->topt.recordSep.separator);
2357 popt->topt.recordSep.separator = pg_strdup(value);
2358 popt->topt.recordSep.separator_zero = false;
2362 if (popt->topt.recordSep.separator_zero)
2363 printf(_("Record separator is zero byte.\n"));
2364 else if (strcmp(popt->topt.recordSep.separator, "\n") == 0)
2365 printf(_("Record separator is <newline>."));
2367 printf(_("Record separator is \"%s\".\n"), popt->topt.recordSep.separator);
2371 else if (strcmp(param, "recordsep_zero") == 0)
2373 free(popt->topt.recordSep.separator);
2374 popt->topt.recordSep.separator = NULL;
2375 popt->topt.recordSep.separator_zero = true;
2377 printf(_("Record separator is zero byte.\n"));
2380 /* toggle between full and tuples-only format */
2381 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
2384 popt->topt.tuples_only = ParseVariableBool(value);
2386 popt->topt.tuples_only = !popt->topt.tuples_only;
2389 if (popt->topt.tuples_only)
2390 puts(_("Showing only tuples."));
2392 puts(_("Tuples only is off."));
2396 /* set title override */
2397 else if (strcmp(param, "title") == 0)
2403 popt->title = pg_strdup(value);
2408 printf(_("Title is \"%s\".\n"), popt->title);
2410 printf(_("Title is unset.\n"));
2414 /* set HTML table tag options */
2415 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
2417 free(popt->topt.tableAttr);
2419 popt->topt.tableAttr = NULL;
2421 popt->topt.tableAttr = pg_strdup(value);
2425 if (popt->topt.tableAttr)
2426 printf(_("Table attribute is \"%s\".\n"), popt->topt.tableAttr);
2428 printf(_("Table attributes unset.\n"));
2432 /* toggle use of pager */
2433 else if (strcmp(param, "pager") == 0)
2435 if (value && pg_strcasecmp(value, "always") == 0)
2436 popt->topt.pager = 2;
2438 if (ParseVariableBool(value))
2439 popt->topt.pager = 1;
2441 popt->topt.pager = 0;
2442 else if (popt->topt.pager == 1)
2443 popt->topt.pager = 0;
2445 popt->topt.pager = 1;
2448 if (popt->topt.pager == 1)
2449 puts(_("Pager is used for long output."));
2450 else if (popt->topt.pager == 2)
2451 puts(_("Pager is always used."));
2453 puts(_("Pager usage is off."));
2457 /* disable "(x rows)" footer */
2458 else if (strcmp(param, "footer") == 0)
2461 popt->topt.default_footer = ParseVariableBool(value);
2463 popt->topt.default_footer = !popt->topt.default_footer;
2466 if (popt->topt.default_footer)
2467 puts(_("Default footer is on."));
2469 puts(_("Default footer is off."));
2473 /* set border style/width */
2474 else if (strcmp(param, "columns") == 0)
2477 popt->topt.columns = atoi(value);
2480 printf(_("Target width is %d.\n"), popt->topt.columns);
2485 psql_error("\\pset: unknown option: %s\n", param);
2495 #define DEFAULT_SHELL "/bin/sh"
2498 * CMD.EXE is in different places in different Win32 releases so we
2499 * have to rely on the path to find it.
2501 #define DEFAULT_SHELL "cmd.exe"
2505 do_shell(const char *command)
2512 const char *shellName;
2514 shellName = getenv("SHELL");
2516 if (shellName == NULL)
2517 shellName = getenv("COMSPEC");
2519 if (shellName == NULL)
2520 shellName = DEFAULT_SHELL;
2522 sys = pg_malloc(strlen(shellName) + 16);
2525 /* See EDITOR handling comment for an explanation */
2526 "exec %s", shellName);
2528 /* See EDITOR handling comment for an explanation */
2529 sprintf(sys, SYSTEMQUOTE "\"%s\"" SYSTEMQUOTE, shellName);
2531 result = system(sys);
2535 result = system(command);
2537 if (result == 127 || result == -1)
2539 psql_error("\\!: failed\n");
2546 * This function takes a function description, e.g. "x" or "x(int)", and
2547 * issues a query on the given connection to retrieve the function's OID
2548 * using a cast to regproc or regprocedure (as appropriate). The result,
2549 * if there is one, is returned at *foid. Note that we'll fail if the
2550 * function doesn't exist OR if there are multiple matching candidates
2551 * OR if there's something syntactically wrong with the function description;
2552 * unfortunately it can be hard to tell the difference.
2555 lookup_function_oid(PGconn *conn, const char *desc, Oid *foid)
2561 query = createPQExpBuffer();
2562 printfPQExpBuffer(query, "SELECT ");
2563 appendStringLiteralConn(query, desc, conn);
2564 appendPQExpBuffer(query, "::pg_catalog.%s::pg_catalog.oid",
2565 strchr(desc, '(') ? "regprocedure" : "regproc");
2567 res = PQexec(conn, query->data);
2568 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
2569 *foid = atooid(PQgetvalue(res, 0, 0));
2572 minimal_error_message(res);
2577 destroyPQExpBuffer(query);
2583 * Fetches the "CREATE OR REPLACE FUNCTION ..." command that describes the
2584 * function with the given OID. If successful, the result is stored in buf.
2587 get_create_function_cmd(PGconn *conn, Oid oid, PQExpBuffer buf)
2593 query = createPQExpBuffer();
2594 printfPQExpBuffer(query, "SELECT pg_catalog.pg_get_functiondef(%u)", oid);
2596 res = PQexec(conn, query->data);
2597 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
2599 resetPQExpBuffer(buf);
2600 appendPQExpBufferStr(buf, PQgetvalue(res, 0, 0));
2604 minimal_error_message(res);
2609 destroyPQExpBuffer(query);
2615 * If the given argument of \ef ends with a line number, delete the line
2616 * number from the argument string and return it as an integer. (We need
2617 * this kluge because we're too lazy to parse \ef's function name argument
2618 * carefully --- we just slop it up in OT_WHOLE_LINE mode.)
2620 * Returns -1 if no line number is present, 0 on error, or a positive value
2624 strip_lineno_from_funcdesc(char *func)
2629 if (!func || func[0] == '\0')
2632 c = func + strlen(func) - 1;
2635 * This business of parsing backwards is dangerous as can be in a
2636 * multibyte environment: there is no reason to believe that we are
2637 * looking at the first byte of a character, nor are we necessarily
2638 * working in a "safe" encoding. Fortunately the bitpatterns we are
2639 * looking for are unlikely to occur as non-first bytes, but beware of
2640 * trying to expand the set of cases that can be recognized. We must
2641 * guard the <ctype.h> macros by using isascii() first, too.
2644 /* skip trailing whitespace */
2645 while (c > func && isascii((unsigned char) *c) && isspace((unsigned char) *c))
2648 /* must have a digit as last non-space char */
2649 if (c == func || !isascii((unsigned char) *c) || !isdigit((unsigned char) *c))
2652 /* find start of digit string */
2653 while (c > func && isascii((unsigned char) *c) && isdigit((unsigned char) *c))
2656 /* digits must be separated from func name by space or closing paren */
2657 /* notice also that we are not allowing an empty func name ... */
2658 if (c == func || !isascii((unsigned char) *c) ||
2659 !(isspace((unsigned char) *c) || *c == ')'))
2662 /* parse digit string */
2667 psql_error("invalid line number: %s\n", c);
2671 /* strip digit string from func */
2678 * Report just the primary error; this is to avoid cluttering the output
2679 * with, for instance, a redisplay of the internally generated query
2682 minimal_error_message(PGresult *res)
2687 msg = createPQExpBuffer();
2689 fld = PQresultErrorField(res, PG_DIAG_SEVERITY);
2691 printfPQExpBuffer(msg, "%s: ", fld);
2693 printfPQExpBuffer(msg, "ERROR: ");
2694 fld = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
2696 appendPQExpBufferStr(msg, fld);
2698 appendPQExpBufferStr(msg, "(not available)");
2699 appendPQExpBufferStr(msg, "\n");
2701 psql_error("%s", msg->data);
2703 destroyPQExpBuffer(msg);