PostgreSQL Source Code  git master
command.c
Go to the documentation of this file.
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2020, PostgreSQL Global Development Group
5  *
6  * src/bin/psql/command.c
7  */
8 #include "postgres_fe.h"
9 
10 #include <ctype.h>
11 #include <time.h>
12 #include <pwd.h>
13 #ifndef WIN32
14 #include <sys/stat.h> /* for stat() */
15 #include <fcntl.h> /* open() flags */
16 #include <unistd.h> /* for geteuid(), getpid(), stat() */
17 #else
18 #include <win32.h>
19 #include <io.h>
20 #include <fcntl.h>
21 #include <direct.h>
22 #include <sys/stat.h> /* for stat() */
23 #endif
24 
25 #include "catalog/pg_class_d.h"
26 #include "command.h"
27 #include "common.h"
28 #include "common/logging.h"
29 #include "copy.h"
30 #include "crosstabview.h"
31 #include "describe.h"
32 #include "fe_utils/cancel.h"
33 #include "fe_utils/print.h"
34 #include "fe_utils/string_utils.h"
35 #include "help.h"
36 #include "input.h"
37 #include "large_obj.h"
38 #include "libpq-fe.h"
39 #include "mainloop.h"
40 #include "portability/instr_time.h"
41 #include "pqexpbuffer.h"
42 #include "psqlscanslash.h"
43 #include "settings.h"
44 #include "variables.h"
45 
46 /*
47  * Editable database object types.
48  */
49 typedef enum EditableObjectType
50 {
54 
55 /* local function declarations */
56 static backslashResult exec_command(const char *cmd,
57  PsqlScanState scan_state,
58  ConditionalStack cstack,
59  PQExpBuffer query_buf,
60  PQExpBuffer previous_buf);
61 static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch);
62 static backslashResult exec_command_C(PsqlScanState scan_state, bool active_branch);
63 static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch);
64 static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch,
65  const char *cmd);
66 static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch);
67 static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch);
68 static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch);
69 static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch);
70 static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch,
71  const char *cmd);
72 static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
73  PQExpBuffer query_buf, PQExpBuffer previous_buf);
74 static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
75  PQExpBuffer query_buf, bool is_func);
76 static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch,
77  const char *cmd);
79  PQExpBuffer query_buf);
81  PQExpBuffer query_buf);
83  PQExpBuffer query_buf);
84 static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch);
85 static backslashResult exec_command_errverbose(PsqlScanState scan_state, bool active_branch);
86 static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch);
87 static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch,
88  const char *cmd);
89 static backslashResult process_command_g_options(char *first_option,
90  PsqlScanState scan_state,
91  bool active_branch,
92  const char *cmd);
93 static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch);
94 static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch);
95 static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch);
96 static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch);
97 static backslashResult exec_command_html(PsqlScanState scan_state, bool active_branch);
98 static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch,
99  const char *cmd);
101  PQExpBuffer query_buf);
102 static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch,
103  const char *cmd);
104 static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_branch,
105  const char *cmd);
106 static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch);
107 static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch,
108  PQExpBuffer query_buf, PQExpBuffer previous_buf);
109 static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch);
110 static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch,
111  const char *cmd);
112 static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch);
113 static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch);
114 static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch,
115  PQExpBuffer query_buf);
116 static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch);
117 static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch);
118 static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch,
119  const char *cmd);
120 static backslashResult exec_command_sf_sv(PsqlScanState scan_state, bool active_branch,
121  const char *cmd, bool is_func);
122 static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch);
123 static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch);
124 static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch);
125 static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch,
126  const char *cmd);
127 static backslashResult exec_command_write(PsqlScanState scan_state, bool active_branch,
128  const char *cmd,
129  PQExpBuffer query_buf, PQExpBuffer previous_buf);
130 static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch,
131  PQExpBuffer query_buf, PQExpBuffer previous_buf);
132 static backslashResult exec_command_x(PsqlScanState scan_state, bool active_branch);
133 static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch);
134 static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch);
135 static backslashResult exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch);
136 static char *read_connect_arg(PsqlScanState scan_state);
138 static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name);
139 static void ignore_boolean_expression(PsqlScanState scan_state);
140 static void ignore_slash_options(PsqlScanState scan_state);
141 static void ignore_slash_filepipe(PsqlScanState scan_state);
142 static void ignore_slash_whole_line(PsqlScanState scan_state);
143 static bool is_branching_command(const char *cmd);
144 static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack,
145  PQExpBuffer query_buf);
146 static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack,
147  PQExpBuffer query_buf);
148 static void copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf);
149 static bool do_connect(enum trivalue reuse_previous_specification,
150  char *dbname, char *user, char *host, char *port);
151 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
152  int lineno, bool *edited);
153 static bool do_shell(const char *command);
154 static bool do_watch(PQExpBuffer query_buf, double sleep);
155 static bool lookup_object_oid(EditableObjectType obj_type, const char *desc,
156  Oid *obj_oid);
157 static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid,
158  PQExpBuffer buf);
159 static int strip_lineno_from_objdesc(char *obj);
161 static void print_with_linenumbers(FILE *output, char *lines,
162  const char *header_keyword);
163 static void minimal_error_message(PGresult *res);
164 
165 static void printSSLInfo(void);
166 static void printGSSInfo(void);
167 static bool printPsetInfo(const char *param, printQueryOpt *popt);
168 static char *pset_value_string(const char *param, printQueryOpt *popt);
169 
170 #ifdef WIN32
171 static void checkWin32Codepage(void);
172 #endif
173 
174 
175 
176 /*----------
177  * HandleSlashCmds:
178  *
179  * Handles all the different commands that start with '\'.
180  * Ordinarily called by MainLoop().
181  *
182  * scan_state is a lexer working state that is set to continue scanning
183  * just after the '\'. The lexer is advanced past the command and all
184  * arguments on return.
185  *
186  * cstack is the current \if stack state. This will be examined, and
187  * possibly modified by conditional commands.
188  *
189  * query_buf contains the query-so-far, which may be modified by
190  * execution of the backslash command (for example, \r clears it).
191  *
192  * previous_buf contains the query most recently sent to the server
193  * (empty if none yet). This should not be modified here, but some
194  * commands copy its content into query_buf.
195  *
196  * query_buf and previous_buf will be NULL when executing a "-c"
197  * command-line option.
198  *
199  * Returns a status code indicating what action is desired, see command.h.
200  *----------
201  */
202 
205  ConditionalStack cstack,
206  PQExpBuffer query_buf,
207  PQExpBuffer previous_buf)
208 {
210  char *cmd;
211  char *arg;
212 
213  Assert(scan_state != NULL);
214  Assert(cstack != NULL);
215 
216  /* Parse off the command name */
217  cmd = psql_scan_slash_command(scan_state);
218 
219  /* And try to execute it */
220  status = exec_command(cmd, scan_state, cstack, query_buf, previous_buf);
221 
222  if (status == PSQL_CMD_UNKNOWN)
223  {
224  pg_log_error("invalid command \\%s", cmd);
226  pg_log_info("Try \\? for help.");
227  status = PSQL_CMD_ERROR;
228  }
229 
230  if (status != PSQL_CMD_ERROR)
231  {
232  /*
233  * Eat any remaining arguments after a valid command. We want to
234  * suppress evaluation of backticks in this situation, so transiently
235  * push an inactive conditional-stack entry.
236  */
237  bool active_branch = conditional_active(cstack);
238 
240  while ((arg = psql_scan_slash_option(scan_state,
241  OT_NORMAL, NULL, false)))
242  {
243  if (active_branch)
244  pg_log_warning("\\%s: extra argument \"%s\" ignored", cmd, arg);
245  free(arg);
246  }
247  conditional_stack_pop(cstack);
248  }
249  else
250  {
251  /* silently throw away rest of line after an erroneous command */
252  while ((arg = psql_scan_slash_option(scan_state,
253  OT_WHOLE_LINE, NULL, false)))
254  free(arg);
255  }
256 
257  /* if there is a trailing \\, swallow it */
258  psql_scan_slash_command_end(scan_state);
259 
260  free(cmd);
261 
262  /* some commands write to queryFout, so make sure output is sent */
263  fflush(pset.queryFout);
264 
265  return status;
266 }
267 
268 
269 /*
270  * Subroutine to actually try to execute a backslash command.
271  *
272  * The typical "success" result code is PSQL_CMD_SKIP_LINE, although some
273  * commands return something else. Failure results are PSQL_CMD_ERROR,
274  * unless PSQL_CMD_UNKNOWN is more appropriate.
275  */
276 static backslashResult
277 exec_command(const char *cmd,
278  PsqlScanState scan_state,
279  ConditionalStack cstack,
280  PQExpBuffer query_buf,
281  PQExpBuffer previous_buf)
282 {
284  bool active_branch = conditional_active(cstack);
285 
286  /*
287  * In interactive mode, warn when we're ignoring a command within a false
288  * \if-branch. But we continue on, so as to parse and discard the right
289  * amount of parameter text. Each individual backslash command subroutine
290  * is responsible for doing nothing after discarding appropriate
291  * arguments, if !active_branch.
292  */
293  if (pset.cur_cmd_interactive && !active_branch &&
294  !is_branching_command(cmd))
295  {
296  pg_log_warning("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block",
297  cmd);
298  }
299 
300  if (strcmp(cmd, "a") == 0)
301  status = exec_command_a(scan_state, active_branch);
302  else if (strcmp(cmd, "C") == 0)
303  status = exec_command_C(scan_state, active_branch);
304  else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
305  status = exec_command_connect(scan_state, active_branch);
306  else if (strcmp(cmd, "cd") == 0)
307  status = exec_command_cd(scan_state, active_branch, cmd);
308  else if (strcmp(cmd, "conninfo") == 0)
309  status = exec_command_conninfo(scan_state, active_branch);
310  else if (pg_strcasecmp(cmd, "copy") == 0)
311  status = exec_command_copy(scan_state, active_branch);
312  else if (strcmp(cmd, "copyright") == 0)
313  status = exec_command_copyright(scan_state, active_branch);
314  else if (strcmp(cmd, "crosstabview") == 0)
315  status = exec_command_crosstabview(scan_state, active_branch);
316  else if (cmd[0] == 'd')
317  status = exec_command_d(scan_state, active_branch, cmd);
318  else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
319  status = exec_command_edit(scan_state, active_branch,
320  query_buf, previous_buf);
321  else if (strcmp(cmd, "ef") == 0)
322  status = exec_command_ef_ev(scan_state, active_branch, query_buf, true);
323  else if (strcmp(cmd, "ev") == 0)
324  status = exec_command_ef_ev(scan_state, active_branch, query_buf, false);
325  else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0 ||
326  strcmp(cmd, "warn") == 0)
327  status = exec_command_echo(scan_state, active_branch, cmd);
328  else if (strcmp(cmd, "elif") == 0)
329  status = exec_command_elif(scan_state, cstack, query_buf);
330  else if (strcmp(cmd, "else") == 0)
331  status = exec_command_else(scan_state, cstack, query_buf);
332  else if (strcmp(cmd, "endif") == 0)
333  status = exec_command_endif(scan_state, cstack, query_buf);
334  else if (strcmp(cmd, "encoding") == 0)
335  status = exec_command_encoding(scan_state, active_branch);
336  else if (strcmp(cmd, "errverbose") == 0)
337  status = exec_command_errverbose(scan_state, active_branch);
338  else if (strcmp(cmd, "f") == 0)
339  status = exec_command_f(scan_state, active_branch);
340  else if (strcmp(cmd, "g") == 0 || strcmp(cmd, "gx") == 0)
341  status = exec_command_g(scan_state, active_branch, cmd);
342  else if (strcmp(cmd, "gdesc") == 0)
343  status = exec_command_gdesc(scan_state, active_branch);
344  else if (strcmp(cmd, "gexec") == 0)
345  status = exec_command_gexec(scan_state, active_branch);
346  else if (strcmp(cmd, "gset") == 0)
347  status = exec_command_gset(scan_state, active_branch);
348  else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
349  status = exec_command_help(scan_state, active_branch);
350  else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
351  status = exec_command_html(scan_state, active_branch);
352  else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0 ||
353  strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
354  status = exec_command_include(scan_state, active_branch, cmd);
355  else if (strcmp(cmd, "if") == 0)
356  status = exec_command_if(scan_state, cstack, query_buf);
357  else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
358  strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
359  status = exec_command_list(scan_state, active_branch, cmd);
360  else if (strncmp(cmd, "lo_", 3) == 0)
361  status = exec_command_lo(scan_state, active_branch, cmd);
362  else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
363  status = exec_command_out(scan_state, active_branch);
364  else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
365  status = exec_command_print(scan_state, active_branch,
366  query_buf, previous_buf);
367  else if (strcmp(cmd, "password") == 0)
368  status = exec_command_password(scan_state, active_branch);
369  else if (strcmp(cmd, "prompt") == 0)
370  status = exec_command_prompt(scan_state, active_branch, cmd);
371  else if (strcmp(cmd, "pset") == 0)
372  status = exec_command_pset(scan_state, active_branch);
373  else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
374  status = exec_command_quit(scan_state, active_branch);
375  else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
376  status = exec_command_reset(scan_state, active_branch, query_buf);
377  else if (strcmp(cmd, "s") == 0)
378  status = exec_command_s(scan_state, active_branch);
379  else if (strcmp(cmd, "set") == 0)
380  status = exec_command_set(scan_state, active_branch);
381  else if (strcmp(cmd, "setenv") == 0)
382  status = exec_command_setenv(scan_state, active_branch, cmd);
383  else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
384  status = exec_command_sf_sv(scan_state, active_branch, cmd, true);
385  else if (strcmp(cmd, "sv") == 0 || strcmp(cmd, "sv+") == 0)
386  status = exec_command_sf_sv(scan_state, active_branch, cmd, false);
387  else if (strcmp(cmd, "t") == 0)
388  status = exec_command_t(scan_state, active_branch);
389  else if (strcmp(cmd, "T") == 0)
390  status = exec_command_T(scan_state, active_branch);
391  else if (strcmp(cmd, "timing") == 0)
392  status = exec_command_timing(scan_state, active_branch);
393  else if (strcmp(cmd, "unset") == 0)
394  status = exec_command_unset(scan_state, active_branch, cmd);
395  else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
396  status = exec_command_write(scan_state, active_branch, cmd,
397  query_buf, previous_buf);
398  else if (strcmp(cmd, "watch") == 0)
399  status = exec_command_watch(scan_state, active_branch,
400  query_buf, previous_buf);
401  else if (strcmp(cmd, "x") == 0)
402  status = exec_command_x(scan_state, active_branch);
403  else if (strcmp(cmd, "z") == 0)
404  status = exec_command_z(scan_state, active_branch);
405  else if (strcmp(cmd, "!") == 0)
406  status = exec_command_shell_escape(scan_state, active_branch);
407  else if (strcmp(cmd, "?") == 0)
408  status = exec_command_slash_command_help(scan_state, active_branch);
409  else
410  status = PSQL_CMD_UNKNOWN;
411 
412  /*
413  * All the commands that return PSQL_CMD_SEND want to execute previous_buf
414  * if query_buf is empty. For convenience we implement that here, not in
415  * the individual command subroutines.
416  */
417  if (status == PSQL_CMD_SEND)
418  copy_previous_query(query_buf, previous_buf);
419 
420  return status;
421 }
422 
423 
424 /*
425  * \a -- toggle field alignment
426  *
427  * This makes little sense but we keep it around.
428  */
429 static backslashResult
430 exec_command_a(PsqlScanState scan_state, bool active_branch)
431 {
432  bool success = true;
433 
434  if (active_branch)
435  {
437  success = do_pset("format", "aligned", &pset.popt, pset.quiet);
438  else
439  success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
440  }
441 
442  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
443 }
444 
445 /*
446  * \C -- override table title (formerly change HTML caption)
447  */
448 static backslashResult
449 exec_command_C(PsqlScanState scan_state, bool active_branch)
450 {
451  bool success = true;
452 
453  if (active_branch)
454  {
455  char *opt = psql_scan_slash_option(scan_state,
456  OT_NORMAL, NULL, true);
457 
458  success = do_pset("title", opt, &pset.popt, pset.quiet);
459  free(opt);
460  }
461  else
462  ignore_slash_options(scan_state);
463 
464  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
465 }
466 
467 /*
468  * \c or \connect -- connect to database using the specified parameters.
469  *
470  * \c [-reuse-previous=BOOL] dbname user host port
471  *
472  * Specifying a parameter as '-' is equivalent to omitting it. Examples:
473  *
474  * \c - - hst Connect to current database on current port of
475  * host "hst" as current user.
476  * \c - usr - prt Connect to current database on port "prt" of current host
477  * as user "usr".
478  * \c dbs Connect to database "dbs" on current port of current host
479  * as current user.
480  */
481 static backslashResult
482 exec_command_connect(PsqlScanState scan_state, bool active_branch)
483 {
484  bool success = true;
485 
486  if (active_branch)
487  {
488  static const char prefix[] = "-reuse-previous=";
489  char *opt1,
490  *opt2,
491  *opt3,
492  *opt4;
493  enum trivalue reuse_previous = TRI_DEFAULT;
494 
495  opt1 = read_connect_arg(scan_state);
496  if (opt1 != NULL && strncmp(opt1, prefix, sizeof(prefix) - 1) == 0)
497  {
498  bool on_off;
499 
500  success = ParseVariableBool(opt1 + sizeof(prefix) - 1,
501  "-reuse-previous",
502  &on_off);
503  if (success)
504  {
505  reuse_previous = on_off ? TRI_YES : TRI_NO;
506  free(opt1);
507  opt1 = read_connect_arg(scan_state);
508  }
509  }
510 
511  if (success) /* give up if reuse_previous was invalid */
512  {
513  opt2 = read_connect_arg(scan_state);
514  opt3 = read_connect_arg(scan_state);
515  opt4 = read_connect_arg(scan_state);
516 
517  success = do_connect(reuse_previous, opt1, opt2, opt3, opt4);
518 
519  free(opt2);
520  free(opt3);
521  free(opt4);
522  }
523  free(opt1);
524  }
525  else
526  ignore_slash_options(scan_state);
527 
528  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
529 }
530 
531 /*
532  * \cd -- change directory
533  */
534 static backslashResult
535 exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
536 {
537  bool success = true;
538 
539  if (active_branch)
540  {
541  char *opt = psql_scan_slash_option(scan_state,
542  OT_NORMAL, NULL, true);
543  char *dir;
544 
545  if (opt)
546  dir = opt;
547  else
548  {
549 #ifndef WIN32
550  struct passwd *pw;
551  uid_t user_id = geteuid();
552 
553  errno = 0; /* clear errno before call */
554  pw = getpwuid(user_id);
555  if (!pw)
556  {
557  pg_log_error("could not get home directory for user ID %ld: %s",
558  (long) user_id,
559  errno ? strerror(errno) : _("user does not exist"));
560  exit(EXIT_FAILURE);
561  }
562  dir = pw->pw_dir;
563 #else /* WIN32 */
564 
565  /*
566  * On Windows, 'cd' without arguments prints the current
567  * directory, so if someone wants to code this here instead...
568  */
569  dir = "/";
570 #endif /* WIN32 */
571  }
572 
573  if (chdir(dir) == -1)
574  {
575  pg_log_error("\\%s: could not change directory to \"%s\": %m",
576  cmd, dir);
577  success = false;
578  }
579 
580  if (opt)
581  free(opt);
582  }
583  else
584  ignore_slash_options(scan_state);
585 
586  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
587 }
588 
589 /*
590  * \conninfo -- display information about the current connection
591  */
592 static backslashResult
593 exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
594 {
595  if (active_branch)
596  {
597  char *db = PQdb(pset.db);
598 
599  if (db == NULL)
600  printf(_("You are currently not connected to a database.\n"));
601  else
602  {
603  char *host = PQhost(pset.db);
604  char *hostaddr = PQhostaddr(pset.db);
605 
606  /*
607  * If the host is an absolute path, the connection is via socket
608  * unless overridden by hostaddr
609  */
610  if (is_absolute_path(host))
611  {
612  if (hostaddr && *hostaddr)
613  printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
614  db, PQuser(pset.db), hostaddr, PQport(pset.db));
615  else
616  printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
617  db, PQuser(pset.db), host, PQport(pset.db));
618  }
619  else
620  {
621  if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
622  printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
623  db, PQuser(pset.db), host, hostaddr, PQport(pset.db));
624  else
625  printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
626  db, PQuser(pset.db), host, PQport(pset.db));
627  }
628  printSSLInfo();
629  printGSSInfo();
630  }
631  }
632 
633  return PSQL_CMD_SKIP_LINE;
634 }
635 
636 /*
637  * \copy -- run a COPY command
638  */
639 static backslashResult
640 exec_command_copy(PsqlScanState scan_state, bool active_branch)
641 {
642  bool success = true;
643 
644  if (active_branch)
645  {
646  char *opt = psql_scan_slash_option(scan_state,
647  OT_WHOLE_LINE, NULL, false);
648 
649  success = do_copy(opt);
650  free(opt);
651  }
652  else
653  ignore_slash_whole_line(scan_state);
654 
655  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
656 }
657 
658 /*
659  * \copyright -- print copyright notice
660  */
661 static backslashResult
662 exec_command_copyright(PsqlScanState scan_state, bool active_branch)
663 {
664  if (active_branch)
665  print_copyright();
666 
667  return PSQL_CMD_SKIP_LINE;
668 }
669 
670 /*
671  * \crosstabview -- execute a query and display results in crosstab
672  */
673 static backslashResult
674 exec_command_crosstabview(PsqlScanState scan_state, bool active_branch)
675 {
677 
678  if (active_branch)
679  {
680  int i;
681 
682  for (i = 0; i < lengthof(pset.ctv_args); i++)
683  pset.ctv_args[i] = psql_scan_slash_option(scan_state,
684  OT_NORMAL, NULL, true);
685  pset.crosstab_flag = true;
686  status = PSQL_CMD_SEND;
687  }
688  else
689  ignore_slash_options(scan_state);
690 
691  return status;
692 }
693 
694 /*
695  * \d* commands
696  */
697 static backslashResult
698 exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
699 {
701  bool success = true;
702 
703  if (active_branch)
704  {
705  char *pattern;
706  bool show_verbose,
707  show_system;
708 
709  /* We don't do SQLID reduction on the pattern yet */
710  pattern = psql_scan_slash_option(scan_state,
711  OT_NORMAL, NULL, true);
712 
713  show_verbose = strchr(cmd, '+') ? true : false;
714  show_system = strchr(cmd, 'S') ? true : false;
715 
716  switch (cmd[1])
717  {
718  case '\0':
719  case '+':
720  case 'S':
721  if (pattern)
722  success = describeTableDetails(pattern, show_verbose, show_system);
723  else
724  /* standard listing of interesting things */
725  success = listTables("tvmsE", NULL, show_verbose, show_system);
726  break;
727  case 'A':
728  {
729  char *pattern2 = NULL;
730 
731  if (pattern && cmd[2] != '\0' && cmd[2] != '+')
732  pattern2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true);
733 
734  switch (cmd[2])
735  {
736  case '\0':
737  case '+':
738  success = describeAccessMethods(pattern, show_verbose);
739  break;
740  case 'c':
741  success = listOperatorClasses(pattern, pattern2, show_verbose);
742  break;
743  case 'f':
744  success = listOperatorFamilies(pattern, pattern2, show_verbose);
745  break;
746  case 'o':
747  success = listOpFamilyOperators(pattern, pattern2, show_verbose);
748  break;
749  case 'p':
750  success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
751  break;
752  default:
753  status = PSQL_CMD_UNKNOWN;
754  break;
755  }
756 
757  if (pattern2)
758  free(pattern2);
759  }
760  break;
761  case 'a':
762  success = describeAggregates(pattern, show_verbose, show_system);
763  break;
764  case 'b':
765  success = describeTablespaces(pattern, show_verbose);
766  break;
767  case 'c':
768  success = listConversions(pattern, show_verbose, show_system);
769  break;
770  case 'C':
771  success = listCasts(pattern, show_verbose);
772  break;
773  case 'd':
774  if (strncmp(cmd, "ddp", 3) == 0)
775  success = listDefaultACLs(pattern);
776  else
777  success = objectDescription(pattern, show_system);
778  break;
779  case 'D':
780  success = listDomains(pattern, show_verbose, show_system);
781  break;
782  case 'f': /* function subsystem */
783  switch (cmd[2])
784  {
785  case '\0':
786  case '+':
787  case 'S':
788  case 'a':
789  case 'n':
790  case 'p':
791  case 't':
792  case 'w':
793  success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
794  break;
795  default:
796  status = PSQL_CMD_UNKNOWN;
797  break;
798  }
799  break;
800  case 'g':
801  /* no longer distinct from \du */
802  success = describeRoles(pattern, show_verbose, show_system);
803  break;
804  case 'l':
805  success = do_lo_list();
806  break;
807  case 'L':
808  success = listLanguages(pattern, show_verbose, show_system);
809  break;
810  case 'n':
811  success = listSchemas(pattern, show_verbose, show_system);
812  break;
813  case 'o':
814  success = describeOperators(pattern, show_verbose, show_system);
815  break;
816  case 'O':
817  success = listCollations(pattern, show_verbose, show_system);
818  break;
819  case 'p':
820  success = permissionsList(pattern);
821  break;
822  case 'P':
823  {
824  switch (cmd[2])
825  {
826  case '\0':
827  case '+':
828  case 't':
829  case 'i':
830  case 'n':
831  success = listPartitionedTables(&cmd[2], pattern, show_verbose);
832  break;
833  default:
834  status = PSQL_CMD_UNKNOWN;
835  break;
836  }
837  }
838  break;
839  case 'T':
840  success = describeTypes(pattern, show_verbose, show_system);
841  break;
842  case 't':
843  case 'v':
844  case 'm':
845  case 'i':
846  case 's':
847  case 'E':
848  success = listTables(&cmd[1], pattern, show_verbose, show_system);
849  break;
850  case 'r':
851  if (cmd[2] == 'd' && cmd[3] == 's')
852  {
853  char *pattern2 = NULL;
854 
855  if (pattern)
856  pattern2 = psql_scan_slash_option(scan_state,
857  OT_NORMAL, NULL, true);
858  success = listDbRoleSettings(pattern, pattern2);
859 
860  if (pattern2)
861  free(pattern2);
862  }
863  else
864  status = PSQL_CMD_UNKNOWN;
865  break;
866  case 'R':
867  switch (cmd[2])
868  {
869  case 'p':
870  if (show_verbose)
871  success = describePublications(pattern);
872  else
873  success = listPublications(pattern);
874  break;
875  case 's':
876  success = describeSubscriptions(pattern, show_verbose);
877  break;
878  default:
879  status = PSQL_CMD_UNKNOWN;
880  }
881  break;
882  case 'u':
883  success = describeRoles(pattern, show_verbose, show_system);
884  break;
885  case 'F': /* text search subsystem */
886  switch (cmd[2])
887  {
888  case '\0':
889  case '+':
890  success = listTSConfigs(pattern, show_verbose);
891  break;
892  case 'p':
893  success = listTSParsers(pattern, show_verbose);
894  break;
895  case 'd':
896  success = listTSDictionaries(pattern, show_verbose);
897  break;
898  case 't':
899  success = listTSTemplates(pattern, show_verbose);
900  break;
901  default:
902  status = PSQL_CMD_UNKNOWN;
903  break;
904  }
905  break;
906  case 'e': /* SQL/MED subsystem */
907  switch (cmd[2])
908  {
909  case 's':
910  success = listForeignServers(pattern, show_verbose);
911  break;
912  case 'u':
913  success = listUserMappings(pattern, show_verbose);
914  break;
915  case 'w':
916  success = listForeignDataWrappers(pattern, show_verbose);
917  break;
918  case 't':
919  success = listForeignTables(pattern, show_verbose);
920  break;
921  default:
922  status = PSQL_CMD_UNKNOWN;
923  break;
924  }
925  break;
926  case 'x': /* Extensions */
927  if (show_verbose)
928  success = listExtensionContents(pattern);
929  else
930  success = listExtensions(pattern);
931  break;
932  case 'y': /* Event Triggers */
933  success = listEventTriggers(pattern, show_verbose);
934  break;
935  default:
936  status = PSQL_CMD_UNKNOWN;
937  }
938 
939  if (pattern)
940  free(pattern);
941  }
942  else
943  ignore_slash_options(scan_state);
944 
945  if (!success)
946  status = PSQL_CMD_ERROR;
947 
948  return status;
949 }
950 
951 /*
952  * \e or \edit -- edit the current query buffer, or edit a file and
953  * make it the query buffer
954  */
955 static backslashResult
956 exec_command_edit(PsqlScanState scan_state, bool active_branch,
957  PQExpBuffer query_buf, PQExpBuffer previous_buf)
958 {
960 
961  if (active_branch)
962  {
963  if (!query_buf)
964  {
965  pg_log_error("no query buffer");
966  status = PSQL_CMD_ERROR;
967  }
968  else
969  {
970  char *fname;
971  char *ln = NULL;
972  int lineno = -1;
973 
974  fname = psql_scan_slash_option(scan_state,
975  OT_NORMAL, NULL, true);
976  if (fname)
977  {
978  /* try to get separate lineno arg */
979  ln = psql_scan_slash_option(scan_state,
980  OT_NORMAL, NULL, true);
981  if (ln == NULL)
982  {
983  /* only one arg; maybe it is lineno not fname */
984  if (fname[0] &&
985  strspn(fname, "0123456789") == strlen(fname))
986  {
987  /* all digits, so assume it is lineno */
988  ln = fname;
989  fname = NULL;
990  }
991  }
992  }
993  if (ln)
994  {
995  lineno = atoi(ln);
996  if (lineno < 1)
997  {
998  pg_log_error("invalid line number: %s", ln);
999  status = PSQL_CMD_ERROR;
1000  }
1001  }
1002  if (status != PSQL_CMD_ERROR)
1003  {
1004  expand_tilde(&fname);
1005  if (fname)
1006  canonicalize_path(fname);
1007 
1008  /* If query_buf is empty, recall previous query for editing */
1009  copy_previous_query(query_buf, previous_buf);
1010 
1011  if (do_edit(fname, query_buf, lineno, NULL))
1012  status = PSQL_CMD_NEWEDIT;
1013  else
1014  status = PSQL_CMD_ERROR;
1015  }
1016  if (fname)
1017  free(fname);
1018  if (ln)
1019  free(ln);
1020  }
1021  }
1022  else
1023  ignore_slash_options(scan_state);
1024 
1025  return status;
1026 }
1027 
1028 /*
1029  * \ef/\ev -- edit the named function/view, or
1030  * present a blank CREATE FUNCTION/VIEW template if no argument is given
1031  */
1032 static backslashResult
1033 exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
1034  PQExpBuffer query_buf, bool is_func)
1035 {
1037 
1038  if (active_branch)
1039  {
1040  char *obj_desc = psql_scan_slash_option(scan_state,
1041  OT_WHOLE_LINE,
1042  NULL, true);
1043  int lineno = -1;
1044 
1045  if (pset.sversion < (is_func ? 80400 : 70400))
1046  {
1047  char sverbuf[32];
1048 
1050  sverbuf, sizeof(sverbuf));
1051  if (is_func)
1052  pg_log_error("The server (version %s) does not support editing function source.",
1053  sverbuf);
1054  else
1055  pg_log_error("The server (version %s) does not support editing view definitions.",
1056  sverbuf);
1057  status = PSQL_CMD_ERROR;
1058  }
1059  else if (!query_buf)
1060  {
1061  pg_log_error("no query buffer");
1062  status = PSQL_CMD_ERROR;
1063  }
1064  else
1065  {
1066  Oid obj_oid = InvalidOid;
1068 
1069  lineno = strip_lineno_from_objdesc(obj_desc);
1070  if (lineno == 0)
1071  {
1072  /* error already reported */
1073  status = PSQL_CMD_ERROR;
1074  }
1075  else if (!obj_desc)
1076  {
1077  /* set up an empty command to fill in */
1078  resetPQExpBuffer(query_buf);
1079  if (is_func)
1080  appendPQExpBufferStr(query_buf,
1081  "CREATE FUNCTION ( )\n"
1082  " RETURNS \n"
1083  " LANGUAGE \n"
1084  " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
1085  "AS $function$\n"
1086  "\n$function$\n");
1087  else
1088  appendPQExpBufferStr(query_buf,
1089  "CREATE VIEW AS\n"
1090  " SELECT \n"
1091  " -- something...\n");
1092  }
1093  else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
1094  {
1095  /* error already reported */
1096  status = PSQL_CMD_ERROR;
1097  }
1098  else if (!get_create_object_cmd(eot, obj_oid, query_buf))
1099  {
1100  /* error already reported */
1101  status = PSQL_CMD_ERROR;
1102  }
1103  else if (is_func && lineno > 0)
1104  {
1105  /*
1106  * lineno "1" should correspond to the first line of the
1107  * function body. We expect that pg_get_functiondef() will
1108  * emit that on a line beginning with "AS ", and that there
1109  * can be no such line before the real start of the function
1110  * body. Increment lineno by the number of lines before that
1111  * line, so that it becomes relative to the first line of the
1112  * function definition.
1113  */
1114  const char *lines = query_buf->data;
1115 
1116  while (*lines != '\0')
1117  {
1118  if (strncmp(lines, "AS ", 3) == 0)
1119  break;
1120  lineno++;
1121  /* find start of next line */
1122  lines = strchr(lines, '\n');
1123  if (!lines)
1124  break;
1125  lines++;
1126  }
1127  }
1128  }
1129 
1130  if (status != PSQL_CMD_ERROR)
1131  {
1132  bool edited = false;
1133 
1134  if (!do_edit(NULL, query_buf, lineno, &edited))
1135  status = PSQL_CMD_ERROR;
1136  else if (!edited)
1137  puts(_("No changes"));
1138  else
1139  status = PSQL_CMD_NEWEDIT;
1140  }
1141 
1142  if (obj_desc)
1143  free(obj_desc);
1144  }
1145  else
1146  ignore_slash_whole_line(scan_state);
1147 
1148  return status;
1149 }
1150 
1151 /*
1152  * \echo, \qecho, and \warn -- echo arguments to stdout, query output, or stderr
1153  */
1154 static backslashResult
1155 exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
1156 {
1157  if (active_branch)
1158  {
1159  char *value;
1160  char quoted;
1161  bool no_newline = false;
1162  bool first = true;
1163  FILE *fout;
1164 
1165  if (strcmp(cmd, "qecho") == 0)
1166  fout = pset.queryFout;
1167  else if (strcmp(cmd, "warn") == 0)
1168  fout = stderr;
1169  else
1170  fout = stdout;
1171 
1172  while ((value = psql_scan_slash_option(scan_state,
1173  OT_NORMAL, &quoted, false)))
1174  {
1175  if (first && !no_newline && !quoted && strcmp(value, "-n") == 0)
1176  no_newline = true;
1177  else
1178  {
1179  if (first)
1180  first = false;
1181  else
1182  fputc(' ', fout);
1183  fputs(value, fout);
1184  }
1185  free(value);
1186  }
1187  if (!no_newline)
1188  fputs("\n", fout);
1189  }
1190  else
1191  ignore_slash_options(scan_state);
1192 
1193  return PSQL_CMD_SKIP_LINE;
1194 }
1195 
1196 /*
1197  * \encoding -- set/show client side encoding
1198  */
1199 static backslashResult
1200 exec_command_encoding(PsqlScanState scan_state, bool active_branch)
1201 {
1202  if (active_branch)
1203  {
1204  char *encoding = psql_scan_slash_option(scan_state,
1205  OT_NORMAL, NULL, false);
1206 
1207  if (!encoding)
1208  {
1209  /* show encoding */
1211  }
1212  else
1213  {
1214  /* set encoding */
1215  if (PQsetClientEncoding(pset.db, encoding) == -1)
1216  pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding);
1217  else
1218  {
1219  /* save encoding info into psql internal data */
1222  SetVariable(pset.vars, "ENCODING",
1224  }
1225  free(encoding);
1226  }
1227  }
1228  else
1229  ignore_slash_options(scan_state);
1230 
1231  return PSQL_CMD_SKIP_LINE;
1232 }
1233 
1234 /*
1235  * \errverbose -- display verbose message from last failed query
1236  */
1237 static backslashResult
1238 exec_command_errverbose(PsqlScanState scan_state, bool active_branch)
1239 {
1240  if (active_branch)
1241  {
1242  if (pset.last_error_result)
1243  {
1244  char *msg;
1245 
1249  if (msg)
1250  {
1251  pg_log_error("%s", msg);
1252  PQfreemem(msg);
1253  }
1254  else
1255  puts(_("out of memory"));
1256  }
1257  else
1258  puts(_("There is no previous error."));
1259  }
1260 
1261  return PSQL_CMD_SKIP_LINE;
1262 }
1263 
1264 /*
1265  * \f -- change field separator
1266  */
1267 static backslashResult
1268 exec_command_f(PsqlScanState scan_state, bool active_branch)
1269 {
1270  bool success = true;
1271 
1272  if (active_branch)
1273  {
1274  char *fname = psql_scan_slash_option(scan_state,
1275  OT_NORMAL, NULL, false);
1276 
1277  success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
1278  free(fname);
1279  }
1280  else
1281  ignore_slash_options(scan_state);
1282 
1283  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1284 }
1285 
1286 /*
1287  * \g [(pset-option[=pset-value] ...)] [filename/shell-command]
1288  * \gx [(pset-option[=pset-value] ...)] [filename/shell-command]
1289  *
1290  * Send the current query. If pset options are specified, they are made
1291  * active just for this query. If a filename or pipe command is given,
1292  * the query output goes there. \gx implicitly sets "expanded=on" along
1293  * with any other pset options that are specified.
1294  */
1295 static backslashResult
1296 exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
1297 {
1299  char *fname;
1300 
1301  /*
1302  * Because the option processing for this is fairly complicated, we do it
1303  * and then decide whether the branch is active.
1304  */
1305  fname = psql_scan_slash_option(scan_state,
1306  OT_FILEPIPE, NULL, false);
1307 
1308  if (fname && fname[0] == '(')
1309  {
1310  /* Consume pset options through trailing ')' ... */
1311  status = process_command_g_options(fname + 1, scan_state,
1312  active_branch, cmd);
1313  free(fname);
1314  /* ... and again attempt to scan the filename. */
1315  fname = psql_scan_slash_option(scan_state,
1316  OT_FILEPIPE, NULL, false);
1317  }
1318 
1319  if (status == PSQL_CMD_SKIP_LINE && active_branch)
1320  {
1321  if (!fname)
1322  pset.gfname = NULL;
1323  else
1324  {
1325  expand_tilde(&fname);
1326  pset.gfname = pg_strdup(fname);
1327  }
1328  if (strcmp(cmd, "gx") == 0)
1329  {
1330  /* save settings if not done already, then force expanded=on */
1331  if (pset.gsavepopt == NULL)
1333  pset.popt.topt.expanded = 1;
1334  }
1335  status = PSQL_CMD_SEND;
1336  }
1337 
1338  free(fname);
1339 
1340  return status;
1341 }
1342 
1343 /*
1344  * Process parenthesized pset options for \g
1345  *
1346  * Note: okay to modify first_option, but not to free it; caller does that
1347  */
1348 static backslashResult
1349 process_command_g_options(char *first_option, PsqlScanState scan_state,
1350  bool active_branch, const char *cmd)
1351 {
1352  bool success = true;
1353  bool found_r_paren = false;
1354 
1355  do
1356  {
1357  char *option;
1358  size_t optlen;
1359 
1360  /* If not first time through, collect a new option */
1361  if (first_option)
1362  option = first_option;
1363  else
1364  {
1365  option = psql_scan_slash_option(scan_state,
1366  OT_NORMAL, NULL, false);
1367  if (!option)
1368  {
1369  if (active_branch)
1370  {
1371  pg_log_error("\\%s: missing right parenthesis", cmd);
1372  success = false;
1373  }
1374  break;
1375  }
1376  }
1377 
1378  /* Check for terminating right paren, and remove it from string */
1379  optlen = strlen(option);
1380  if (optlen > 0 && option[optlen - 1] == ')')
1381  {
1382  option[--optlen] = '\0';
1383  found_r_paren = true;
1384  }
1385 
1386  /* If there was anything besides parentheses, parse/execute it */
1387  if (optlen > 0)
1388  {
1389  /* We can have either "name" or "name=value" */
1390  char *valptr = strchr(option, '=');
1391 
1392  if (valptr)
1393  *valptr++ = '\0';
1394  if (active_branch)
1395  {
1396  /* save settings if not done already, then apply option */
1397  if (pset.gsavepopt == NULL)
1399  success &= do_pset(option, valptr, &pset.popt, true);
1400  }
1401  }
1402 
1403  /* Clean up after this option. We should not free first_option. */
1404  if (first_option)
1405  first_option = NULL;
1406  else
1407  free(option);
1408  } while (!found_r_paren);
1409 
1410  /* If we failed after already changing some options, undo side-effects */
1411  if (!success && active_branch && pset.gsavepopt)
1412  {
1414  pset.gsavepopt = NULL;
1415  }
1416 
1417  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1418 }
1419 
1420 /*
1421  * \gdesc -- describe query result
1422  */
1423 static backslashResult
1424 exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
1425 {
1427 
1428  if (active_branch)
1429  {
1430  pset.gdesc_flag = true;
1431  status = PSQL_CMD_SEND;
1432  }
1433 
1434  return status;
1435 }
1436 
1437 /*
1438  * \gexec -- send query and execute each field of result
1439  */
1440 static backslashResult
1441 exec_command_gexec(PsqlScanState scan_state, bool active_branch)
1442 {
1444 
1445  if (active_branch)
1446  {
1447  pset.gexec_flag = true;
1448  status = PSQL_CMD_SEND;
1449  }
1450 
1451  return status;
1452 }
1453 
1454 /*
1455  * \gset [prefix] -- send query and store result into variables
1456  */
1457 static backslashResult
1458 exec_command_gset(PsqlScanState scan_state, bool active_branch)
1459 {
1461 
1462  if (active_branch)
1463  {
1464  char *prefix = psql_scan_slash_option(scan_state,
1465  OT_NORMAL, NULL, false);
1466 
1467  if (prefix)
1468  pset.gset_prefix = prefix;
1469  else
1470  {
1471  /* we must set a non-NULL prefix to trigger storing */
1472  pset.gset_prefix = pg_strdup("");
1473  }
1474  /* gset_prefix is freed later */
1475  status = PSQL_CMD_SEND;
1476  }
1477  else
1478  ignore_slash_options(scan_state);
1479 
1480  return status;
1481 }
1482 
1483 /*
1484  * \help [topic] -- print help about SQL commands
1485  */
1486 static backslashResult
1487 exec_command_help(PsqlScanState scan_state, bool active_branch)
1488 {
1489  if (active_branch)
1490  {
1491  char *opt = psql_scan_slash_option(scan_state,
1492  OT_WHOLE_LINE, NULL, false);
1493  size_t len;
1494 
1495  /* strip any trailing spaces and semicolons */
1496  if (opt)
1497  {
1498  len = strlen(opt);
1499  while (len > 0 &&
1500  (isspace((unsigned char) opt[len - 1])
1501  || opt[len - 1] == ';'))
1502  opt[--len] = '\0';
1503  }
1504 
1505  helpSQL(opt, pset.popt.topt.pager);
1506  free(opt);
1507  }
1508  else
1509  ignore_slash_whole_line(scan_state);
1510 
1511  return PSQL_CMD_SKIP_LINE;
1512 }
1513 
1514 /*
1515  * \H and \html -- toggle HTML formatting
1516  */
1517 static backslashResult
1518 exec_command_html(PsqlScanState scan_state, bool active_branch)
1519 {
1520  bool success = true;
1521 
1522  if (active_branch)
1523  {
1524  if (pset.popt.topt.format != PRINT_HTML)
1525  success = do_pset("format", "html", &pset.popt, pset.quiet);
1526  else
1527  success = do_pset("format", "aligned", &pset.popt, pset.quiet);
1528  }
1529 
1530  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1531 }
1532 
1533 /*
1534  * \i and \ir -- include a file
1535  */
1536 static backslashResult
1537 exec_command_include(PsqlScanState scan_state, bool active_branch, const char *cmd)
1538 {
1539  bool success = true;
1540 
1541  if (active_branch)
1542  {
1543  char *fname = psql_scan_slash_option(scan_state,
1544  OT_NORMAL, NULL, true);
1545 
1546  if (!fname)
1547  {
1548  pg_log_error("\\%s: missing required argument", cmd);
1549  success = false;
1550  }
1551  else
1552  {
1553  bool include_relative;
1554 
1555  include_relative = (strcmp(cmd, "ir") == 0
1556  || strcmp(cmd, "include_relative") == 0);
1557  expand_tilde(&fname);
1558  success = (process_file(fname, include_relative) == EXIT_SUCCESS);
1559  free(fname);
1560  }
1561  }
1562  else
1563  ignore_slash_options(scan_state);
1564 
1565  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1566 }
1567 
1568 /*
1569  * \if <expr> -- beginning of an \if..\endif block
1570  *
1571  * <expr> is parsed as a boolean expression. Invalid expressions will emit a
1572  * warning and be treated as false. Statements that follow a false expression
1573  * will be parsed but ignored. Note that in the case where an \if statement
1574  * is itself within an inactive section of a block, then the entire inner
1575  * \if..\endif block will be parsed but ignored.
1576  */
1577 static backslashResult
1579  PQExpBuffer query_buf)
1580 {
1581  if (conditional_active(cstack))
1582  {
1583  /*
1584  * First, push a new active stack entry; this ensures that the lexer
1585  * will perform variable substitution and backtick evaluation while
1586  * scanning the expression. (That should happen anyway, since we know
1587  * we're in an active outer branch, but let's be sure.)
1588  */
1590 
1591  /* Remember current query state in case we need to restore later */
1592  save_query_text_state(scan_state, cstack, query_buf);
1593 
1594  /*
1595  * Evaluate the expression; if it's false, change to inactive state.
1596  */
1597  if (!is_true_boolean_expression(scan_state, "\\if expression"))
1599  }
1600  else
1601  {
1602  /*
1603  * We're within an inactive outer branch, so this entire \if block
1604  * will be ignored. We don't want to evaluate the expression, so push
1605  * the "ignored" stack state before scanning it.
1606  */
1608 
1609  /* Remember current query state in case we need to restore later */
1610  save_query_text_state(scan_state, cstack, query_buf);
1611 
1612  ignore_boolean_expression(scan_state);
1613  }
1614 
1615  return PSQL_CMD_SKIP_LINE;
1616 }
1617 
1618 /*
1619  * \elif <expr> -- alternative branch in an \if..\endif block
1620  *
1621  * <expr> is evaluated the same as in \if <expr>.
1622  */
1623 static backslashResult
1625  PQExpBuffer query_buf)
1626 {
1627  bool success = true;
1628 
1629  switch (conditional_stack_peek(cstack))
1630  {
1631  case IFSTATE_TRUE:
1632 
1633  /*
1634  * Just finished active branch of this \if block. Update saved
1635  * state so we will keep whatever data was put in query_buf by the
1636  * active branch.
1637  */
1638  save_query_text_state(scan_state, cstack, query_buf);
1639 
1640  /*
1641  * Discard \elif expression and ignore the rest until \endif.
1642  * Switch state before reading expression to ensure proper lexer
1643  * behavior.
1644  */
1646  ignore_boolean_expression(scan_state);
1647  break;
1648  case IFSTATE_FALSE:
1649 
1650  /*
1651  * Discard any query text added by the just-skipped branch.
1652  */
1653  discard_query_text(scan_state, cstack, query_buf);
1654 
1655  /*
1656  * Have not yet found a true expression in this \if block, so this
1657  * might be the first. We have to change state before examining
1658  * the expression, or the lexer won't do the right thing.
1659  */
1661  if (!is_true_boolean_expression(scan_state, "\\elif expression"))
1663  break;
1664  case IFSTATE_IGNORED:
1665 
1666  /*
1667  * Discard any query text added by the just-skipped branch.
1668  */
1669  discard_query_text(scan_state, cstack, query_buf);
1670 
1671  /*
1672  * Skip expression and move on. Either the \if block already had
1673  * an active section, or whole block is being skipped.
1674  */
1675  ignore_boolean_expression(scan_state);
1676  break;
1677  case IFSTATE_ELSE_TRUE:
1678  case IFSTATE_ELSE_FALSE:
1679  pg_log_error("\\elif: cannot occur after \\else");
1680  success = false;
1681  break;
1682  case IFSTATE_NONE:
1683  /* no \if to elif from */
1684  pg_log_error("\\elif: no matching \\if");
1685  success = false;
1686  break;
1687  }
1688 
1689  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1690 }
1691 
1692 /*
1693  * \else -- final alternative in an \if..\endif block
1694  *
1695  * Statements within an \else branch will only be executed if
1696  * all previous \if and \elif expressions evaluated to false
1697  * and the block was not itself being ignored.
1698  */
1699 static backslashResult
1701  PQExpBuffer query_buf)
1702 {
1703  bool success = true;
1704 
1705  switch (conditional_stack_peek(cstack))
1706  {
1707  case IFSTATE_TRUE:
1708 
1709  /*
1710  * Just finished active branch of this \if block. Update saved
1711  * state so we will keep whatever data was put in query_buf by the
1712  * active branch.
1713  */
1714  save_query_text_state(scan_state, cstack, query_buf);
1715 
1716  /* Now skip the \else branch */
1718  break;
1719  case IFSTATE_FALSE:
1720 
1721  /*
1722  * Discard any query text added by the just-skipped branch.
1723  */
1724  discard_query_text(scan_state, cstack, query_buf);
1725 
1726  /*
1727  * We've not found any true \if or \elif expression, so execute
1728  * the \else branch.
1729  */
1731  break;
1732  case IFSTATE_IGNORED:
1733 
1734  /*
1735  * Discard any query text added by the just-skipped branch.
1736  */
1737  discard_query_text(scan_state, cstack, query_buf);
1738 
1739  /*
1740  * Either we previously processed the active branch of this \if,
1741  * or the whole \if block is being skipped. Either way, skip the
1742  * \else branch.
1743  */
1745  break;
1746  case IFSTATE_ELSE_TRUE:
1747  case IFSTATE_ELSE_FALSE:
1748  pg_log_error("\\else: cannot occur after \\else");
1749  success = false;
1750  break;
1751  case IFSTATE_NONE:
1752  /* no \if to else from */
1753  pg_log_error("\\else: no matching \\if");
1754  success = false;
1755  break;
1756  }
1757 
1758  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1759 }
1760 
1761 /*
1762  * \endif -- ends an \if...\endif block
1763  */
1764 static backslashResult
1766  PQExpBuffer query_buf)
1767 {
1768  bool success = true;
1769 
1770  switch (conditional_stack_peek(cstack))
1771  {
1772  case IFSTATE_TRUE:
1773  case IFSTATE_ELSE_TRUE:
1774  /* Close the \if block, keeping the query text */
1775  success = conditional_stack_pop(cstack);
1776  Assert(success);
1777  break;
1778  case IFSTATE_FALSE:
1779  case IFSTATE_IGNORED:
1780  case IFSTATE_ELSE_FALSE:
1781 
1782  /*
1783  * Discard any query text added by the just-skipped branch.
1784  */
1785  discard_query_text(scan_state, cstack, query_buf);
1786 
1787  /* Close the \if block */
1788  success = conditional_stack_pop(cstack);
1789  Assert(success);
1790  break;
1791  case IFSTATE_NONE:
1792  /* no \if to end */
1793  pg_log_error("\\endif: no matching \\if");
1794  success = false;
1795  break;
1796  }
1797 
1798  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1799 }
1800 
1801 /*
1802  * \l -- list databases
1803  */
1804 static backslashResult
1805 exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
1806 {
1807  bool success = true;
1808 
1809  if (active_branch)
1810  {
1811  char *pattern;
1812  bool show_verbose;
1813 
1814  pattern = psql_scan_slash_option(scan_state,
1815  OT_NORMAL, NULL, true);
1816 
1817  show_verbose = strchr(cmd, '+') ? true : false;
1818 
1819  success = listAllDbs(pattern, show_verbose);
1820 
1821  if (pattern)
1822  free(pattern);
1823  }
1824  else
1825  ignore_slash_options(scan_state);
1826 
1827  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1828 }
1829 
1830 /*
1831  * \lo_* -- large object operations
1832  */
1833 static backslashResult
1834 exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
1835 {
1837  bool success = true;
1838 
1839  if (active_branch)
1840  {
1841  char *opt1,
1842  *opt2;
1843 
1844  opt1 = psql_scan_slash_option(scan_state,
1845  OT_NORMAL, NULL, true);
1846  opt2 = psql_scan_slash_option(scan_state,
1847  OT_NORMAL, NULL, true);
1848 
1849  if (strcmp(cmd + 3, "export") == 0)
1850  {
1851  if (!opt2)
1852  {
1853  pg_log_error("\\%s: missing required argument", cmd);
1854  success = false;
1855  }
1856  else
1857  {
1858  expand_tilde(&opt2);
1859  success = do_lo_export(opt1, opt2);
1860  }
1861  }
1862 
1863  else if (strcmp(cmd + 3, "import") == 0)
1864  {
1865  if (!opt1)
1866  {
1867  pg_log_error("\\%s: missing required argument", cmd);
1868  success = false;
1869  }
1870  else
1871  {
1872  expand_tilde(&opt1);
1873  success = do_lo_import(opt1, opt2);
1874  }
1875  }
1876 
1877  else if (strcmp(cmd + 3, "list") == 0)
1878  success = do_lo_list();
1879 
1880  else if (strcmp(cmd + 3, "unlink") == 0)
1881  {
1882  if (!opt1)
1883  {
1884  pg_log_error("\\%s: missing required argument", cmd);
1885  success = false;
1886  }
1887  else
1888  success = do_lo_unlink(opt1);
1889  }
1890 
1891  else
1892  status = PSQL_CMD_UNKNOWN;
1893 
1894  free(opt1);
1895  free(opt2);
1896  }
1897  else
1898  ignore_slash_options(scan_state);
1899 
1900  if (!success)
1901  status = PSQL_CMD_ERROR;
1902 
1903  return status;
1904 }
1905 
1906 /*
1907  * \o -- set query output
1908  */
1909 static backslashResult
1910 exec_command_out(PsqlScanState scan_state, bool active_branch)
1911 {
1912  bool success = true;
1913 
1914  if (active_branch)
1915  {
1916  char *fname = psql_scan_slash_option(scan_state,
1917  OT_FILEPIPE, NULL, true);
1918 
1919  expand_tilde(&fname);
1920  success = setQFout(fname);
1921  free(fname);
1922  }
1923  else
1924  ignore_slash_filepipe(scan_state);
1925 
1926  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1927 }
1928 
1929 /*
1930  * \p -- print the current query buffer
1931  */
1932 static backslashResult
1933 exec_command_print(PsqlScanState scan_state, bool active_branch,
1934  PQExpBuffer query_buf, PQExpBuffer previous_buf)
1935 {
1936  if (active_branch)
1937  {
1938  /*
1939  * We want to print the same thing \g would execute, but not to change
1940  * the query buffer state; so we can't use copy_previous_query().
1941  * Also, beware of possibility that buffer pointers are NULL.
1942  */
1943  if (query_buf && query_buf->len > 0)
1944  puts(query_buf->data);
1945  else if (previous_buf && previous_buf->len > 0)
1946  puts(previous_buf->data);
1947  else if (!pset.quiet)
1948  puts(_("Query buffer is empty."));
1949  fflush(stdout);
1950  }
1951 
1952  return PSQL_CMD_SKIP_LINE;
1953 }
1954 
1955 /*
1956  * \password -- set user password
1957  */
1958 static backslashResult
1959 exec_command_password(PsqlScanState scan_state, bool active_branch)
1960 {
1961  bool success = true;
1962 
1963  if (active_branch)
1964  {
1965  char *opt0 = psql_scan_slash_option(scan_state,
1966  OT_SQLID, NULL, true);
1967  char pw1[100];
1968  char pw2[100];
1969 
1970  simple_prompt("Enter new password: ", pw1, sizeof(pw1), false);
1971  simple_prompt("Enter it again: ", pw2, sizeof(pw2), false);
1972 
1973  if (strcmp(pw1, pw2) != 0)
1974  {
1975  pg_log_error("Passwords didn't match.");
1976  success = false;
1977  }
1978  else
1979  {
1980  char *user;
1981  char *encrypted_password;
1982 
1983  if (opt0)
1984  user = opt0;
1985  else
1986  user = PQuser(pset.db);
1987 
1988  encrypted_password = PQencryptPasswordConn(pset.db, pw1, user, NULL);
1989 
1990  if (!encrypted_password)
1991  {
1993  success = false;
1994  }
1995  else
1996  {
1998  PGresult *res;
1999 
2000  initPQExpBuffer(&buf);
2001  printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
2002  fmtId(user));
2003  appendStringLiteralConn(&buf, encrypted_password, pset.db);
2004  res = PSQLexec(buf.data);
2005  termPQExpBuffer(&buf);
2006  if (!res)
2007  success = false;
2008  else
2009  PQclear(res);
2010  PQfreemem(encrypted_password);
2011  }
2012  }
2013 
2014  if (opt0)
2015  free(opt0);
2016  }
2017  else
2018  ignore_slash_options(scan_state);
2019 
2020  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2021 }
2022 
2023 /*
2024  * \prompt -- prompt and set variable
2025  */
2026 static backslashResult
2027 exec_command_prompt(PsqlScanState scan_state, bool active_branch,
2028  const char *cmd)
2029 {
2030  bool success = true;
2031 
2032  if (active_branch)
2033  {
2034  char *opt,
2035  *prompt_text = NULL;
2036  char *arg1,
2037  *arg2;
2038 
2039  arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
2040  arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
2041 
2042  if (!arg1)
2043  {
2044  pg_log_error("\\%s: missing required argument", cmd);
2045  success = false;
2046  }
2047  else
2048  {
2049  char *result;
2050 
2051  if (arg2)
2052  {
2053  prompt_text = arg1;
2054  opt = arg2;
2055  }
2056  else
2057  opt = arg1;
2058 
2059  if (!pset.inputfile)
2060  {
2061  result = (char *) pg_malloc(4096);
2062  simple_prompt(prompt_text, result, 4096, true);
2063  }
2064  else
2065  {
2066  if (prompt_text)
2067  {
2068  fputs(prompt_text, stdout);
2069  fflush(stdout);
2070  }
2071  result = gets_fromFile(stdin);
2072  if (!result)
2073  {
2074  pg_log_error("\\%s: could not read value for variable",
2075  cmd);
2076  success = false;
2077  }
2078  }
2079 
2080  if (result &&
2081  !SetVariable(pset.vars, opt, result))
2082  success = false;
2083 
2084  if (result)
2085  free(result);
2086  if (prompt_text)
2087  free(prompt_text);
2088  free(opt);
2089  }
2090  }
2091  else
2092  ignore_slash_options(scan_state);
2093 
2094  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2095 }
2096 
2097 /*
2098  * \pset -- set printing parameters
2099  */
2100 static backslashResult
2101 exec_command_pset(PsqlScanState scan_state, bool active_branch)
2102 {
2103  bool success = true;
2104 
2105  if (active_branch)
2106  {
2107  char *opt0 = psql_scan_slash_option(scan_state,
2108  OT_NORMAL, NULL, false);
2109  char *opt1 = psql_scan_slash_option(scan_state,
2110  OT_NORMAL, NULL, false);
2111 
2112  if (!opt0)
2113  {
2114  /* list all variables */
2115 
2116  int i;
2117  static const char *const my_list[] = {
2118  "border", "columns", "csv_fieldsep", "expanded", "fieldsep",
2119  "fieldsep_zero", "footer", "format", "linestyle", "null",
2120  "numericlocale", "pager", "pager_min_lines",
2121  "recordsep", "recordsep_zero",
2122  "tableattr", "title", "tuples_only",
2123  "unicode_border_linestyle",
2124  "unicode_column_linestyle",
2125  "unicode_header_linestyle",
2126  NULL
2127  };
2128 
2129  for (i = 0; my_list[i] != NULL; i++)
2130  {
2131  char *val = pset_value_string(my_list[i], &pset.popt);
2132 
2133  printf("%-24s %s\n", my_list[i], val);
2134  free(val);
2135  }
2136 
2137  success = true;
2138  }
2139  else
2140  success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
2141 
2142  free(opt0);
2143  free(opt1);
2144  }
2145  else
2146  ignore_slash_options(scan_state);
2147 
2148  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2149 }
2150 
2151 /*
2152  * \q or \quit -- exit psql
2153  */
2154 static backslashResult
2155 exec_command_quit(PsqlScanState scan_state, bool active_branch)
2156 {
2158 
2159  if (active_branch)
2160  status = PSQL_CMD_TERMINATE;
2161 
2162  return status;
2163 }
2164 
2165 /*
2166  * \r -- reset (clear) the query buffer
2167  */
2168 static backslashResult
2169 exec_command_reset(PsqlScanState scan_state, bool active_branch,
2170  PQExpBuffer query_buf)
2171 {
2172  if (active_branch)
2173  {
2174  resetPQExpBuffer(query_buf);
2175  psql_scan_reset(scan_state);
2176  if (!pset.quiet)
2177  puts(_("Query buffer reset (cleared)."));
2178  }
2179 
2180  return PSQL_CMD_SKIP_LINE;
2181 }
2182 
2183 /*
2184  * \s -- save history in a file or show it on the screen
2185  */
2186 static backslashResult
2187 exec_command_s(PsqlScanState scan_state, bool active_branch)
2188 {
2189  bool success = true;
2190 
2191  if (active_branch)
2192  {
2193  char *fname = psql_scan_slash_option(scan_state,
2194  OT_NORMAL, NULL, true);
2195 
2196  expand_tilde(&fname);
2197  success = printHistory(fname, pset.popt.topt.pager);
2198  if (success && !pset.quiet && fname)
2199  printf(_("Wrote history to file \"%s\".\n"), fname);
2200  if (!fname)
2201  putchar('\n');
2202  free(fname);
2203  }
2204  else
2205  ignore_slash_options(scan_state);
2206 
2207  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2208 }
2209 
2210 /*
2211  * \set -- set variable
2212  */
2213 static backslashResult
2214 exec_command_set(PsqlScanState scan_state, bool active_branch)
2215 {
2216  bool success = true;
2217 
2218  if (active_branch)
2219  {
2220  char *opt0 = psql_scan_slash_option(scan_state,
2221  OT_NORMAL, NULL, false);
2222 
2223  if (!opt0)
2224  {
2225  /* list all variables */
2227  success = true;
2228  }
2229  else
2230  {
2231  /*
2232  * Set variable to the concatenation of the arguments.
2233  */
2234  char *newval;
2235  char *opt;
2236 
2237  opt = psql_scan_slash_option(scan_state,
2238  OT_NORMAL, NULL, false);
2239  newval = pg_strdup(opt ? opt : "");
2240  free(opt);
2241 
2242  while ((opt = psql_scan_slash_option(scan_state,
2243  OT_NORMAL, NULL, false)))
2244  {
2245  newval = pg_realloc(newval, strlen(newval) + strlen(opt) + 1);
2246  strcat(newval, opt);
2247  free(opt);
2248  }
2249 
2250  if (!SetVariable(pset.vars, opt0, newval))
2251  success = false;
2252 
2253  free(newval);
2254  }
2255  free(opt0);
2256  }
2257  else
2258  ignore_slash_options(scan_state);
2259 
2260  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2261 }
2262 
2263 /*
2264  * \setenv -- set environment variable
2265  */
2266 static backslashResult
2267 exec_command_setenv(PsqlScanState scan_state, bool active_branch,
2268  const char *cmd)
2269 {
2270  bool success = true;
2271 
2272  if (active_branch)
2273  {
2274  char *envvar = psql_scan_slash_option(scan_state,
2275  OT_NORMAL, NULL, false);
2276  char *envval = psql_scan_slash_option(scan_state,
2277  OT_NORMAL, NULL, false);
2278 
2279  if (!envvar)
2280  {
2281  pg_log_error("\\%s: missing required argument", cmd);
2282  success = false;
2283  }
2284  else if (strchr(envvar, '=') != NULL)
2285  {
2286  pg_log_error("\\%s: environment variable name must not contain \"=\"",
2287  cmd);
2288  success = false;
2289  }
2290  else if (!envval)
2291  {
2292  /* No argument - unset the environment variable */
2293  unsetenv(envvar);
2294  success = true;
2295  }
2296  else
2297  {
2298  /* Set variable to the value of the next argument */
2299  char *newval;
2300 
2301  newval = psprintf("%s=%s", envvar, envval);
2302  putenv(newval);
2303  success = true;
2304 
2305  /*
2306  * Do not free newval here, it will screw up the environment if
2307  * you do. See putenv man page for details. That means we leak a
2308  * bit of memory here, but not enough to worry about.
2309  */
2310  }
2311  free(envvar);
2312  free(envval);
2313  }
2314  else
2315  ignore_slash_options(scan_state);
2316 
2317  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2318 }
2319 
2320 /*
2321  * \sf/\sv -- show a function/view's source code
2322  */
2323 static backslashResult
2324 exec_command_sf_sv(PsqlScanState scan_state, bool active_branch,
2325  const char *cmd, bool is_func)
2326 {
2328 
2329  if (active_branch)
2330  {
2331  bool show_linenumbers = (strchr(cmd, '+') != NULL);
2332  PQExpBuffer buf;
2333  char *obj_desc;
2334  Oid obj_oid = InvalidOid;
2336 
2337  buf = createPQExpBuffer();
2338  obj_desc = psql_scan_slash_option(scan_state,
2339  OT_WHOLE_LINE, NULL, true);
2340  if (pset.sversion < (is_func ? 80400 : 70400))
2341  {
2342  char sverbuf[32];
2343 
2345  sverbuf, sizeof(sverbuf));
2346  if (is_func)
2347  pg_log_error("The server (version %s) does not support showing function source.",
2348  sverbuf);
2349  else
2350  pg_log_error("The server (version %s) does not support showing view definitions.",
2351  sverbuf);
2352  status = PSQL_CMD_ERROR;
2353  }
2354  else if (!obj_desc)
2355  {
2356  if (is_func)
2357  pg_log_error("function name is required");
2358  else
2359  pg_log_error("view name is required");
2360  status = PSQL_CMD_ERROR;
2361  }
2362  else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
2363  {
2364  /* error already reported */
2365  status = PSQL_CMD_ERROR;
2366  }
2367  else if (!get_create_object_cmd(eot, obj_oid, buf))
2368  {
2369  /* error already reported */
2370  status = PSQL_CMD_ERROR;
2371  }
2372  else
2373  {
2374  FILE *output;
2375  bool is_pager;
2376 
2377  /* Select output stream: stdout, pager, or file */
2378  if (pset.queryFout == stdout)
2379  {
2380  /* count lines in function to see if pager is needed */
2381  int lineno = count_lines_in_buf(buf);
2382 
2383  output = PageOutput(lineno, &(pset.popt.topt));
2384  is_pager = true;
2385  }
2386  else
2387  {
2388  /* use previously set output file, without pager */
2389  output = pset.queryFout;
2390  is_pager = false;
2391  }
2392 
2393  if (show_linenumbers)
2394  {
2395  /*
2396  * For functions, lineno "1" should correspond to the first
2397  * line of the function body. We expect that
2398  * pg_get_functiondef() will emit that on a line beginning
2399  * with "AS ", and that there can be no such line before the
2400  * real start of the function body.
2401  */
2402  print_with_linenumbers(output, buf->data,
2403  is_func ? "AS " : NULL);
2404  }
2405  else
2406  {
2407  /* just send the definition to output */
2408  fputs(buf->data, output);
2409  }
2410 
2411  if (is_pager)
2412  ClosePager(output);
2413  }
2414 
2415  if (obj_desc)
2416  free(obj_desc);
2417  destroyPQExpBuffer(buf);
2418  }
2419  else
2420  ignore_slash_whole_line(scan_state);
2421 
2422  return status;
2423 }
2424 
2425 /*
2426  * \t -- turn off table headers and row count
2427  */
2428 static backslashResult
2429 exec_command_t(PsqlScanState scan_state, bool active_branch)
2430 {
2431  bool success = true;
2432 
2433  if (active_branch)
2434  {
2435  char *opt = psql_scan_slash_option(scan_state,
2436  OT_NORMAL, NULL, true);
2437 
2438  success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
2439  free(opt);
2440  }
2441  else
2442  ignore_slash_options(scan_state);
2443 
2444  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2445 }
2446 
2447 /*
2448  * \T -- define html <table ...> attributes
2449  */
2450 static backslashResult
2451 exec_command_T(PsqlScanState scan_state, bool active_branch)
2452 {
2453  bool success = true;
2454 
2455  if (active_branch)
2456  {
2457  char *value = psql_scan_slash_option(scan_state,
2458  OT_NORMAL, NULL, false);
2459 
2460  success = do_pset("tableattr", value, &pset.popt, pset.quiet);
2461  free(value);
2462  }
2463  else
2464  ignore_slash_options(scan_state);
2465 
2466  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2467 }
2468 
2469 /*
2470  * \timing -- enable/disable timing of queries
2471  */
2472 static backslashResult
2473 exec_command_timing(PsqlScanState scan_state, bool active_branch)
2474 {
2475  bool success = true;
2476 
2477  if (active_branch)
2478  {
2479  char *opt = psql_scan_slash_option(scan_state,
2480  OT_NORMAL, NULL, false);
2481 
2482  if (opt)
2483  success = ParseVariableBool(opt, "\\timing", &pset.timing);
2484  else
2485  pset.timing = !pset.timing;
2486  if (!pset.quiet)
2487  {
2488  if (pset.timing)
2489  puts(_("Timing is on."));
2490  else
2491  puts(_("Timing is off."));
2492  }
2493  free(opt);
2494  }
2495  else
2496  ignore_slash_options(scan_state);
2497 
2498  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2499 }
2500 
2501 /*
2502  * \unset -- unset variable
2503  */
2504 static backslashResult
2505 exec_command_unset(PsqlScanState scan_state, bool active_branch,
2506  const char *cmd)
2507 {
2508  bool success = true;
2509 
2510  if (active_branch)
2511  {
2512  char *opt = psql_scan_slash_option(scan_state,
2513  OT_NORMAL, NULL, false);
2514 
2515  if (!opt)
2516  {
2517  pg_log_error("\\%s: missing required argument", cmd);
2518  success = false;
2519  }
2520  else if (!SetVariable(pset.vars, opt, NULL))
2521  success = false;
2522 
2523  free(opt);
2524  }
2525  else
2526  ignore_slash_options(scan_state);
2527 
2528  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2529 }
2530 
2531 /*
2532  * \w -- write query buffer to file
2533  */
2534 static backslashResult
2535 exec_command_write(PsqlScanState scan_state, bool active_branch,
2536  const char *cmd,
2537  PQExpBuffer query_buf, PQExpBuffer previous_buf)
2538 {
2540 
2541  if (active_branch)
2542  {
2543  char *fname = psql_scan_slash_option(scan_state,
2544  OT_FILEPIPE, NULL, true);
2545  FILE *fd = NULL;
2546  bool is_pipe = false;
2547 
2548  if (!query_buf)
2549  {
2550  pg_log_error("no query buffer");
2551  status = PSQL_CMD_ERROR;
2552  }
2553  else
2554  {
2555  if (!fname)
2556  {
2557  pg_log_error("\\%s: missing required argument", cmd);
2558  status = PSQL_CMD_ERROR;
2559  }
2560  else
2561  {
2562  expand_tilde(&fname);
2563  if (fname[0] == '|')
2564  {
2565  is_pipe = true;
2567  fd = popen(&fname[1], "w");
2568  }
2569  else
2570  {
2571  canonicalize_path(fname);
2572  fd = fopen(fname, "w");
2573  }
2574  if (!fd)
2575  {
2576  pg_log_error("%s: %m", fname);
2577  status = PSQL_CMD_ERROR;
2578  }
2579  }
2580  }
2581 
2582  if (fd)
2583  {
2584  int result;
2585 
2586  /*
2587  * We want to print the same thing \g would execute, but not to
2588  * change the query buffer state; so we can't use
2589  * copy_previous_query(). Also, beware of possibility that buffer
2590  * pointers are NULL.
2591  */
2592  if (query_buf && query_buf->len > 0)
2593  fprintf(fd, "%s\n", query_buf->data);
2594  else if (previous_buf && previous_buf->len > 0)
2595  fprintf(fd, "%s\n", previous_buf->data);
2596 
2597  if (is_pipe)
2598  result = pclose(fd);
2599  else
2600  result = fclose(fd);
2601 
2602  if (result == EOF)
2603  {
2604  pg_log_error("%s: %m", fname);
2605  status = PSQL_CMD_ERROR;
2606  }
2607  }
2608 
2609  if (is_pipe)
2611 
2612  free(fname);
2613  }
2614  else
2615  ignore_slash_filepipe(scan_state);
2616 
2617  return status;
2618 }
2619 
2620 /*
2621  * \watch -- execute a query every N seconds
2622  */
2623 static backslashResult
2624 exec_command_watch(PsqlScanState scan_state, bool active_branch,
2625  PQExpBuffer query_buf, PQExpBuffer previous_buf)
2626 {
2627  bool success = true;
2628 
2629  if (active_branch)
2630  {
2631  char *opt = psql_scan_slash_option(scan_state,
2632  OT_NORMAL, NULL, true);
2633  double sleep = 2;
2634 
2635  /* Convert optional sleep-length argument */
2636  if (opt)
2637  {
2638  sleep = strtod(opt, NULL);
2639  if (sleep <= 0)
2640  sleep = 1;
2641  free(opt);
2642  }
2643 
2644  /* If query_buf is empty, recall and execute previous query */
2645  copy_previous_query(query_buf, previous_buf);
2646 
2647  success = do_watch(query_buf, sleep);
2648 
2649  /* Reset the query buffer as though for \r */
2650  resetPQExpBuffer(query_buf);
2651  psql_scan_reset(scan_state);
2652  }
2653  else
2654  ignore_slash_options(scan_state);
2655 
2656  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2657 }
2658 
2659 /*
2660  * \x -- set or toggle expanded table representation
2661  */
2662 static backslashResult
2663 exec_command_x(PsqlScanState scan_state, bool active_branch)
2664 {
2665  bool success = true;
2666 
2667  if (active_branch)
2668  {
2669  char *opt = psql_scan_slash_option(scan_state,
2670  OT_NORMAL, NULL, true);
2671 
2672  success = do_pset("expanded", opt, &pset.popt, pset.quiet);
2673  free(opt);
2674  }
2675  else
2676  ignore_slash_options(scan_state);
2677 
2678  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2679 }
2680 
2681 /*
2682  * \z -- list table privileges (equivalent to \dp)
2683  */
2684 static backslashResult
2685 exec_command_z(PsqlScanState scan_state, bool active_branch)
2686 {
2687  bool success = true;
2688 
2689  if (active_branch)
2690  {
2691  char *pattern = psql_scan_slash_option(scan_state,
2692  OT_NORMAL, NULL, true);
2693 
2694  success = permissionsList(pattern);
2695  if (pattern)
2696  free(pattern);
2697  }
2698  else
2699  ignore_slash_options(scan_state);
2700 
2701  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2702 }
2703 
2704 /*
2705  * \! -- execute shell command
2706  */
2707 static backslashResult
2708 exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
2709 {
2710  bool success = true;
2711 
2712  if (active_branch)
2713  {
2714  char *opt = psql_scan_slash_option(scan_state,
2715  OT_WHOLE_LINE, NULL, false);
2716 
2717  success = do_shell(opt);
2718  free(opt);
2719  }
2720  else
2721  ignore_slash_whole_line(scan_state);
2722 
2723  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2724 }
2725 
2726 /*
2727  * \? -- print help about backslash commands
2728  */
2729 static backslashResult
2730 exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch)
2731 {
2732  if (active_branch)
2733  {
2734  char *opt0 = psql_scan_slash_option(scan_state,
2735  OT_NORMAL, NULL, false);
2736 
2737  if (!opt0 || strcmp(opt0, "commands") == 0)
2739  else if (strcmp(opt0, "options") == 0)
2741  else if (strcmp(opt0, "variables") == 0)
2743  else
2745 
2746  if (opt0)
2747  free(opt0);
2748  }
2749  else
2750  ignore_slash_options(scan_state);
2751 
2752  return PSQL_CMD_SKIP_LINE;
2753 }
2754 
2755 
2756 /*
2757  * Read and interpret an argument to the \connect slash command.
2758  *
2759  * Returns a malloc'd string, or NULL if no/empty argument.
2760  */
2761 static char *
2763 {
2764  char *result;
2765  char quote;
2766 
2767  /*
2768  * Ideally we should treat the arguments as SQL identifiers. But for
2769  * backwards compatibility with 7.2 and older pg_dump files, we have to
2770  * take unquoted arguments verbatim (don't downcase them). For now,
2771  * double-quoted arguments may be stripped of double quotes (as if SQL
2772  * identifiers). By 7.4 or so, pg_dump files can be expected to
2773  * double-quote all mixed-case \connect arguments, and then we can get rid
2774  * of OT_SQLIDHACK.
2775  */
2776  result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, &quote, true);
2777 
2778  if (!result)
2779  return NULL;
2780 
2781  if (quote)
2782  return result;
2783 
2784  if (*result == '\0' || strcmp(result, "-") == 0)
2785  {
2786  free(result);
2787  return NULL;
2788  }
2789 
2790  return result;
2791 }
2792 
2793 /*
2794  * Read a boolean expression, return it as a PQExpBuffer string.
2795  *
2796  * Note: anything more or less than one token will certainly fail to be
2797  * parsed by ParseVariableBool, so we don't worry about complaining here.
2798  * This routine's return data structure will need to be rethought anyway
2799  * to support likely future extensions such as "\if defined VARNAME".
2800  */
2801 static PQExpBuffer
2803 {
2804  PQExpBuffer exp_buf = createPQExpBuffer();
2805  int num_options = 0;
2806  char *value;
2807 
2808  /* collect all arguments for the conditional command into exp_buf */
2809  while ((value = psql_scan_slash_option(scan_state,
2810  OT_NORMAL, NULL, false)) != NULL)
2811  {
2812  /* add spaces between tokens */
2813  if (num_options > 0)
2814  appendPQExpBufferChar(exp_buf, ' ');
2815  appendPQExpBufferStr(exp_buf, value);
2816  num_options++;
2817  free(value);
2818  }
2819 
2820  return exp_buf;
2821 }
2822 
2823 /*
2824  * Read a boolean expression, return true if the expression
2825  * was a valid boolean expression that evaluated to true.
2826  * Otherwise return false.
2827  *
2828  * Note: conditional stack's top state must be active, else lexer will
2829  * fail to expand variables and backticks.
2830  */
2831 static bool
2833 {
2835  bool value = false;
2836  bool success = ParseVariableBool(buf->data, name, &value);
2837 
2838  destroyPQExpBuffer(buf);
2839  return success && value;
2840 }
2841 
2842 /*
2843  * Read a boolean expression, but do nothing with it.
2844  *
2845  * Note: conditional stack's top state must be INACTIVE, else lexer will
2846  * expand variables and backticks, which we do not want here.
2847  */
2848 static void
2850 {
2852 
2853  destroyPQExpBuffer(buf);
2854 }
2855 
2856 /*
2857  * Read and discard "normal" slash command options.
2858  *
2859  * This should be used for inactive-branch processing of any slash command
2860  * that eats one or more OT_NORMAL, OT_SQLID, or OT_SQLIDHACK parameters.
2861  * We don't need to worry about exactly how many it would eat, since the
2862  * cleanup logic in HandleSlashCmds would silently discard any extras anyway.
2863  */
2864 static void
2866 {
2867  char *arg;
2868 
2869  while ((arg = psql_scan_slash_option(scan_state,
2870  OT_NORMAL, NULL, false)) != NULL)
2871  free(arg);
2872 }
2873 
2874 /*
2875  * Read and discard FILEPIPE slash command argument.
2876  *
2877  * This *MUST* be used for inactive-branch processing of any slash command
2878  * that takes an OT_FILEPIPE option. Otherwise we might consume a different
2879  * amount of option text in active and inactive cases.
2880  */
2881 static void
2883 {
2884  char *arg = psql_scan_slash_option(scan_state,
2885  OT_FILEPIPE, NULL, false);
2886 
2887  if (arg)
2888  free(arg);
2889 }
2890 
2891 /*
2892  * Read and discard whole-line slash command argument.
2893  *
2894  * This *MUST* be used for inactive-branch processing of any slash command
2895  * that takes an OT_WHOLE_LINE option. Otherwise we might consume a different
2896  * amount of option text in active and inactive cases.
2897  */
2898 static void
2900 {
2901  char *arg = psql_scan_slash_option(scan_state,
2902  OT_WHOLE_LINE, NULL, false);
2903 
2904  if (arg)
2905  free(arg);
2906 }
2907 
2908 /*
2909  * Return true if the command given is a branching command.
2910  */
2911 static bool
2912 is_branching_command(const char *cmd)
2913 {
2914  return (strcmp(cmd, "if") == 0 ||
2915  strcmp(cmd, "elif") == 0 ||
2916  strcmp(cmd, "else") == 0 ||
2917  strcmp(cmd, "endif") == 0);
2918 }
2919 
2920 /*
2921  * Prepare to possibly restore query buffer to its current state
2922  * (cf. discard_query_text).
2923  *
2924  * We need to remember the length of the query buffer, and the lexer's
2925  * notion of the parenthesis nesting depth.
2926  */
2927 static void
2929  PQExpBuffer query_buf)
2930 {
2931  if (query_buf)
2932  conditional_stack_set_query_len(cstack, query_buf->len);
2934  psql_scan_get_paren_depth(scan_state));
2935 }
2936 
2937 /*
2938  * Discard any query text absorbed during an inactive conditional branch.
2939  *
2940  * We must discard data that was appended to query_buf during an inactive
2941  * \if branch. We don't have to do anything there if there's no query_buf.
2942  *
2943  * Also, reset the lexer state to the same paren depth there was before.
2944  * (The rest of its state doesn't need attention, since we could not be
2945  * inside a comment or literal or partial token.)
2946  */
2947 static void
2949  PQExpBuffer query_buf)
2950 {
2951  if (query_buf)
2952  {
2953  int new_len = conditional_stack_get_query_len(cstack);
2954 
2955  Assert(new_len >= 0 && new_len <= query_buf->len);
2956  query_buf->len = new_len;
2957  query_buf->data[new_len] = '\0';
2958  }
2959  psql_scan_set_paren_depth(scan_state,
2961 }
2962 
2963 /*
2964  * If query_buf is empty, copy previous_buf into it.
2965  *
2966  * This is used by various slash commands for which re-execution of a
2967  * previous query is a common usage. For convenience, we allow the
2968  * case of query_buf == NULL (and do nothing).
2969  */
2970 static void
2972 {
2973  if (query_buf && query_buf->len == 0)
2974  appendPQExpBufferStr(query_buf, previous_buf->data);
2975 }
2976 
2977 /*
2978  * Ask the user for a password; 'username' is the username the
2979  * password is for, if one has been explicitly specified. Returns a
2980  * malloc'd string.
2981  */
2982 static char *
2984 {
2985  char buf[100];
2986 
2987  if (username == NULL || username[0] == '\0')
2988  simple_prompt("Password: ", buf, sizeof(buf), false);
2989  else
2990  {
2991  char *prompt_text;
2992 
2993  prompt_text = psprintf(_("Password for user %s: "), username);
2994  simple_prompt(prompt_text, buf, sizeof(buf), false);
2995  free(prompt_text);
2996  }
2997  return pg_strdup(buf);
2998 }
2999 
3000 static bool
3001 param_is_newly_set(const char *old_val, const char *new_val)
3002 {
3003  if (new_val == NULL)
3004  return false;
3005 
3006  if (old_val == NULL || strcmp(old_val, new_val) != 0)
3007  return true;
3008 
3009  return false;
3010 }
3011 
3012 /* return whether the connection has 'hostaddr' in its conninfo */
3013 static bool
3015 {
3016  bool used = false;
3017  PQconninfoOption *ciopt = PQconninfo(conn);
3018 
3019  for (PQconninfoOption *p = ciopt; p->keyword != NULL; p++)
3020  {
3021  if (strcmp(p->keyword, "hostaddr") == 0 && p->val != NULL)
3022  {
3023  used = true;
3024  break;
3025  }
3026  }
3027 
3028  PQconninfoFree(ciopt);
3029  return used;
3030 }
3031 
3032 /*
3033  * do_connect -- handler for \connect
3034  *
3035  * Connects to a database with given parameters. Absent an established
3036  * connection, all parameters are required. Given -reuse-previous=off or a
3037  * connection string without -reuse-previous=on, NULL values will pass through
3038  * to PQconnectdbParams(), so the libpq defaults will be used. Otherwise, NULL
3039  * values will be replaced with the ones in the current connection.
3040  *
3041  * In interactive mode, if connection fails with the given parameters,
3042  * the old connection will be kept.
3043  */
3044 static bool
3045 do_connect(enum trivalue reuse_previous_specification,
3046  char *dbname, char *user, char *host, char *port)
3047 {
3048  PGconn *o_conn = pset.db,
3049  *n_conn;
3050  char *password = NULL;
3051  char *hostaddr = NULL;
3052  bool keep_password;
3053  bool has_connection_string;
3054  bool reuse_previous;
3056 
3057  if (!o_conn && (!dbname || !user || !host || !port))
3058  {
3059  /*
3060  * We don't know the supplied connection parameters and don't want to
3061  * connect to the wrong database by using defaults, so require all
3062  * parameters to be specified.
3063  */
3064  pg_log_error("All connection parameters must be supplied because no "
3065  "database connection exists");
3066  return false;
3067  }
3068 
3069  has_connection_string = dbname ?
3070  recognized_connection_string(dbname) : false;
3071  switch (reuse_previous_specification)
3072  {
3073  case TRI_YES:
3074  reuse_previous = true;
3075  break;
3076  case TRI_NO:
3077  reuse_previous = false;
3078  break;
3079  default:
3080  reuse_previous = !has_connection_string;
3081  break;
3082  }
3083 
3084  /* If the old connection does not exist, there is nothing to reuse. */
3085  if (!o_conn)
3086  reuse_previous = false;
3087 
3088  /* Silently ignore arguments subsequent to a connection string. */
3089  if (has_connection_string)
3090  {
3091  user = NULL;
3092  host = NULL;
3093  port = NULL;
3094  }
3095 
3096  /*
3097  * Grab missing values from the old connection. If we grab host (or host
3098  * is the same as before) and hostaddr was set, grab that too.
3099  */
3100  if (reuse_previous)
3101  {
3102  if (!user)
3103  user = PQuser(o_conn);
3104  if (host && strcmp(host, PQhost(o_conn)) == 0 &&
3105  has_hostaddr(o_conn))
3106  {
3107  hostaddr = PQhostaddr(o_conn);
3108  }
3109  if (!host)
3110  {
3111  host = PQhost(o_conn);
3112  if (has_hostaddr(o_conn))
3113  hostaddr = PQhostaddr(o_conn);
3114  }
3115  if (!port)
3116  port = PQport(o_conn);
3117  }
3118 
3119  /*
3120  * Any change in the parameters read above makes us discard the password.
3121  * We also discard it if we're to use a conninfo rather than the
3122  * positional syntax.
3123  */
3124  if (has_connection_string)
3125  keep_password = false;
3126  else
3127  keep_password =
3128  (user && PQuser(o_conn) && strcmp(user, PQuser(o_conn)) == 0) &&
3129  (host && PQhost(o_conn) && strcmp(host, PQhost(o_conn)) == 0) &&
3130  (port && PQport(o_conn) && strcmp(port, PQport(o_conn)) == 0);
3131 
3132  /*
3133  * Grab missing dbname from old connection. No password discard if this
3134  * changes: passwords aren't (usually) database-specific.
3135  */
3136  if (!dbname && reuse_previous)
3137  {
3138  initPQExpBuffer(&connstr);
3139  appendPQExpBufferStr(&connstr, "dbname=");
3140  appendConnStrVal(&connstr, PQdb(o_conn));
3141  dbname = connstr.data;
3142  /* has_connection_string=true would be a dead store */
3143  }
3144  else
3145  connstr.data = NULL;
3146 
3147  /*
3148  * If the user asked to be prompted for a password, ask for one now. If
3149  * not, use the password from the old connection, provided the username
3150  * etc have not changed. Otherwise, try to connect without a password
3151  * first, and then ask for a password if needed.
3152  *
3153  * XXX: this behavior leads to spurious connection attempts recorded in
3154  * the postmaster's log. But libpq offers no API that would let us obtain
3155  * a password and then continue with the first connection attempt.
3156  */
3157  if (pset.getPassword == TRI_YES)
3158  {
3159  /*
3160  * If a connstring or URI is provided, we can't be sure we know which
3161  * username will be used, since we haven't parsed that argument yet.
3162  * Don't risk issuing a misleading prompt. As in startup.c, it does
3163  * not seem worth working harder, since this getPassword option is
3164  * normally only used in noninteractive cases.
3165  */
3166  password = prompt_for_password(has_connection_string ? NULL : user);
3167  }
3168  else if (o_conn && keep_password)
3169  {
3170  password = PQpass(o_conn);
3171  if (password && *password)
3172  password = pg_strdup(password);
3173  else
3174  password = NULL;
3175  }
3176 
3177  while (true)
3178  {
3179 #define PARAMS_ARRAY_SIZE 9
3180  const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
3181  const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
3182  int paramnum = -1;
3183 
3184  keywords[++paramnum] = "host";
3185  values[paramnum] = host;
3186  if (hostaddr && *hostaddr)
3187  {
3188  keywords[++paramnum] = "hostaddr";
3189  values[paramnum] = hostaddr;
3190  }
3191  keywords[++paramnum] = "port";
3192  values[paramnum] = port;
3193  keywords[++paramnum] = "user";
3194  values[paramnum] = user;
3195 
3196  /*
3197  * Position in the array matters when the dbname is a connection
3198  * string, because settings in a connection string override earlier
3199  * array entries only. Thus, user= in the connection string always
3200  * takes effect, but client_encoding= often will not.
3201  *
3202  * If you change this code, also change the initial-connection code in
3203  * main(). For no good reason, a connection string password= takes
3204  * precedence in main() but not here.
3205  */
3206  keywords[++paramnum] = "dbname";
3207  values[paramnum] = dbname;
3208  keywords[++paramnum] = "password";
3209  values[paramnum] = password;
3210  keywords[++paramnum] = "fallback_application_name";
3211  values[paramnum] = pset.progname;
3212  keywords[++paramnum] = "client_encoding";
3213  values[paramnum] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto";
3214 
3215  /* add array terminator */
3216  keywords[++paramnum] = NULL;
3217  values[paramnum] = NULL;
3218 
3219  n_conn = PQconnectdbParams(keywords, values, true);
3220 
3221  pg_free(keywords);
3222  pg_free(values);
3223 
3224  /* We can immediately discard the password -- no longer needed */
3225  if (password)
3226  pg_free(password);
3227 
3228  if (PQstatus(n_conn) == CONNECTION_OK)
3229  break;
3230 
3231  /*
3232  * Connection attempt failed; either retry the connection attempt with
3233  * a new password, or give up.
3234  */
3235  if (!password && PQconnectionNeedsPassword(n_conn) && pset.getPassword != TRI_NO)
3236  {
3237  /*
3238  * Prompt for password using the username we actually connected
3239  * with --- it might've come out of "dbname" rather than "user".
3240  */
3241  password = prompt_for_password(PQuser(n_conn));
3242  PQfinish(n_conn);
3243  continue;
3244  }
3245 
3246  /*
3247  * Failed to connect to the database. In interactive mode, keep the
3248  * previous connection to the DB; in scripting mode, close our
3249  * previous connection as well.
3250  */
3252  {
3253  pg_log_info("%s", PQerrorMessage(n_conn));
3254 
3255  /* pset.db is left unmodified */
3256  if (o_conn)
3257  pg_log_info("Previous connection kept");
3258  }
3259  else
3260  {
3261  pg_log_error("\\connect: %s", PQerrorMessage(n_conn));
3262  if (o_conn)
3263  {
3264  /*
3265  * Transition to having no connection. Keep this bit in sync
3266  * with CheckConnection().
3267  */
3268  PQfinish(o_conn);
3269  pset.db = NULL;
3270  ResetCancelConn();
3271  UnsyncVariables();
3272  }
3273  }
3274 
3275  PQfinish(n_conn);
3276  if (connstr.data)
3277  termPQExpBuffer(&connstr);
3278  return false;
3279  }
3280  if (connstr.data)
3281  termPQExpBuffer(&connstr);
3282 
3283  /*
3284  * Replace the old connection with the new one, and update
3285  * connection-dependent variables. Keep the resynchronization logic in
3286  * sync with CheckConnection().
3287  */
3288  PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
3289  pset.db = n_conn;
3290  SyncVariables();
3291  connection_warnings(false); /* Must be after SyncVariables */
3292 
3293  /* Tell the user about the new connection */
3294  if (!pset.quiet)
3295  {
3296  if (!o_conn ||
3297  param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) ||
3298  param_is_newly_set(PQport(o_conn), PQport(pset.db)))
3299  {
3300  char *host = PQhost(pset.db);
3301  char *hostaddr = PQhostaddr(pset.db);
3302 
3303  /*
3304  * If the host is an absolute path, the connection is via socket
3305  * unless overridden by hostaddr
3306  */
3307  if (is_absolute_path(host))
3308  {
3309  if (hostaddr && *hostaddr)
3310  printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
3311  PQdb(pset.db), PQuser(pset.db), hostaddr, PQport(pset.db));
3312  else
3313  printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
3314  PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
3315  }
3316  else
3317  {
3318  if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
3319  printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
3320  PQdb(pset.db), PQuser(pset.db), host, hostaddr, PQport(pset.db));
3321  else
3322  printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
3323  PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
3324  }
3325  }
3326  else
3327  printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
3328  PQdb(pset.db), PQuser(pset.db));
3329  }
3330 
3331  if (o_conn)
3332  PQfinish(o_conn);
3333  return true;
3334 }
3335 
3336 
3337 void
3338 connection_warnings(bool in_startup)
3339 {
3340  if (!pset.quiet && !pset.notty)
3341  {
3342  int client_ver = PG_VERSION_NUM;
3343  char cverbuf[32];
3344  char sverbuf[32];
3345 
3346  if (pset.sversion != client_ver)
3347  {
3348  const char *server_version;
3349 
3350  /* Try to get full text form, might include "devel" etc */
3351  server_version = PQparameterStatus(pset.db, "server_version");
3352  /* Otherwise fall back on pset.sversion */
3353  if (!server_version)
3354  {
3356  sverbuf, sizeof(sverbuf));
3357  server_version = sverbuf;
3358  }
3359 
3360  printf(_("%s (%s, server %s)\n"),
3361  pset.progname, PG_VERSION, server_version);
3362  }
3363  /* For version match, only print psql banner on startup. */
3364  else if (in_startup)
3365  printf("%s (%s)\n", pset.progname, PG_VERSION);
3366 
3367  if (pset.sversion / 100 > client_ver / 100)
3368  printf(_("WARNING: %s major version %s, server major version %s.\n"
3369  " Some psql features might not work.\n"),
3370  pset.progname,
3371  formatPGVersionNumber(client_ver, false,
3372  cverbuf, sizeof(cverbuf)),
3374  sverbuf, sizeof(sverbuf)));
3375 
3376 #ifdef WIN32
3377  if (in_startup)
3378  checkWin32Codepage();
3379 #endif
3380  printSSLInfo();
3381  printGSSInfo();
3382  }
3383 }
3384 
3385 
3386 /*
3387  * printSSLInfo
3388  *
3389  * Prints information about the current SSL connection, if SSL is in use
3390  */
3391 static void
3393 {
3394  const char *protocol;
3395  const char *cipher;
3396  const char *bits;
3397  const char *compression;
3398 
3399  if (!PQsslInUse(pset.db))
3400  return; /* no SSL */
3401 
3402  protocol = PQsslAttribute(pset.db, "protocol");
3403  cipher = PQsslAttribute(pset.db, "cipher");
3404  bits = PQsslAttribute(pset.db, "key_bits");
3405  compression = PQsslAttribute(pset.db, "compression");
3406 
3407  printf(_("SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n"),
3408  protocol ? protocol : _("unknown"),
3409  cipher ? cipher : _("unknown"),
3410  bits ? bits : _("unknown"),
3411  (compression && strcmp(compression, "off") != 0) ? _("on") : _("off"));
3412 }
3413 
3414 /*
3415  * printGSSInfo
3416  *
3417  * Prints information about the current GSSAPI connection, if GSSAPI encryption is in use
3418  */
3419 static void
3421 {
3422  if (!PQgssEncInUse(pset.db))
3423  return; /* no GSSAPI encryption in use */
3424 
3425  printf(_("GSSAPI-encrypted connection\n"));
3426 }
3427 
3428 
3429 /*
3430  * checkWin32Codepage
3431  *
3432  * Prints a warning when win32 console codepage differs from Windows codepage
3433  */
3434 #ifdef WIN32
3435 static void
3436 checkWin32Codepage(void)
3437 {
3438  unsigned int wincp,
3439  concp;
3440 
3441  wincp = GetACP();
3442  concp = GetConsoleCP();
3443  if (wincp != concp)
3444  {
3445  printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
3446  " 8-bit characters might not work correctly. See psql reference\n"
3447  " page \"Notes for Windows users\" for details.\n"),
3448  concp, wincp);
3449  }
3450 }
3451 #endif
3452 
3453 
3454 /*
3455  * SyncVariables
3456  *
3457  * Make psql's internal variables agree with connection state upon
3458  * establishing a new connection.
3459  */
3460 void
3462 {
3463  char vbuf[32];
3464  const char *server_version;
3465 
3466  /* get stuff from connection */
3470 
3471  SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
3472  SetVariable(pset.vars, "USER", PQuser(pset.db));
3473  SetVariable(pset.vars, "HOST", PQhost(pset.db));
3474  SetVariable(pset.vars, "PORT", PQport(pset.db));
3476 
3477  /* this bit should match connection_warnings(): */
3478  /* Try to get full text form of version, might include "devel" etc */
3479  server_version = PQparameterStatus(pset.db, "server_version");
3480  /* Otherwise fall back on pset.sversion */
3481  if (!server_version)
3482  {
3483  formatPGVersionNumber(pset.sversion, true, vbuf, sizeof(vbuf));
3484  server_version = vbuf;
3485  }
3486  SetVariable(pset.vars, "SERVER_VERSION_NAME", server_version);
3487 
3488  snprintf(vbuf, sizeof(vbuf), "%d", pset.sversion);
3489  SetVariable(pset.vars, "SERVER_VERSION_NUM", vbuf);
3490 
3491  /* send stuff to it, too */
3494 }
3495 
3496 /*
3497  * UnsyncVariables
3498  *
3499  * Clear variables that should be not be set when there is no connection.
3500  */
3501 void
3503 {
3504  SetVariable(pset.vars, "DBNAME", NULL);
3505  SetVariable(pset.vars, "USER", NULL);
3506  SetVariable(pset.vars, "HOST", NULL);
3507  SetVariable(pset.vars, "PORT", NULL);
3508  SetVariable(pset.vars, "ENCODING", NULL);
3509  SetVariable(pset.vars, "SERVER_VERSION_NAME", NULL);
3510  SetVariable(pset.vars, "SERVER_VERSION_NUM", NULL);
3511 }
3512 
3513 
3514 /*
3515  * do_edit -- handler for \e
3516  *
3517  * If you do not specify a filename, the current query buffer will be copied
3518  * into a temporary one.
3519  */
3520 static bool
3521 editFile(const char *fname, int lineno)
3522 {
3523  const char *editorName;
3524  const char *editor_lineno_arg = NULL;
3525  char *sys;
3526  int result;
3527 
3528  Assert(fname != NULL);
3529 
3530  /* Find an editor to use */
3531  editorName = getenv("PSQL_EDITOR");
3532  if (!editorName)
3533  editorName = getenv("EDITOR");
3534  if (!editorName)
3535  editorName = getenv("VISUAL");
3536  if (!editorName)
3537  editorName = DEFAULT_EDITOR;
3538 
3539  /* Get line number argument, if we need it. */
3540  if (lineno > 0)
3541  {
3542  editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
3543 #ifdef DEFAULT_EDITOR_LINENUMBER_ARG
3544  if (!editor_lineno_arg)
3545  editor_lineno_arg = DEFAULT_EDITOR_LINENUMBER_ARG;
3546 #endif
3547  if (!editor_lineno_arg)
3548  {
3549  pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number");
3550  return false;
3551  }
3552  }
3553 
3554  /*
3555  * On Unix the EDITOR value should *not* be quoted, since it might include
3556  * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
3557  * if necessary. But this policy is not very workable on Windows, due to
3558  * severe brain damage in their command shell plus the fact that standard
3559  * program paths include spaces.
3560  */
3561 #ifndef WIN32
3562  if (lineno > 0)
3563  sys = psprintf("exec %s %s%d '%s'",
3564  editorName, editor_lineno_arg, lineno, fname);
3565  else
3566  sys = psprintf("exec %s '%s'",
3567  editorName, fname);
3568 #else
3569  if (lineno > 0)
3570  sys = psprintf("\"%s\" %s%d \"%s\"",
3571  editorName, editor_lineno_arg, lineno, fname);
3572  else
3573  sys = psprintf("\"%s\" \"%s\"",
3574  editorName, fname);
3575 #endif
3576  result = system(sys);
3577  if (result == -1)
3578  pg_log_error("could not start editor \"%s\"", editorName);
3579  else if (result == 127)
3580  pg_log_error("could not start /bin/sh");
3581  free(sys);
3582 
3583  return result == 0;
3584 }
3585 
3586 
3587 /* call this one */
3588 static bool
3589 do_edit(const char *filename_arg, PQExpBuffer query_buf,
3590  int lineno, bool *edited)
3591 {
3592  char fnametmp[MAXPGPATH];
3593  FILE *stream = NULL;
3594  const char *fname;
3595  bool error = false;
3596  int fd;
3597 
3598  struct stat before,
3599  after;
3600 
3601  if (filename_arg)
3602  fname = filename_arg;
3603  else
3604  {
3605  /* make a temp file to edit */
3606 #ifndef WIN32
3607  const char *tmpdir = getenv("TMPDIR");
3608 
3609  if (!tmpdir)
3610  tmpdir = "/tmp";
3611 #else
3612  char tmpdir[MAXPGPATH];
3613  int ret;
3614 
3615  ret = GetTempPath(MAXPGPATH, tmpdir);
3616  if (ret == 0 || ret > MAXPGPATH)
3617  {
3618  pg_log_error("could not locate temporary directory: %s",
3619  !ret ? strerror(errno) : "");
3620  return false;
3621  }
3622 
3623  /*
3624  * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
3625  * current directory to the supplied path unless we use only
3626  * backslashes, so we do that.
3627  */
3628 #endif
3629 #ifndef WIN32
3630  snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
3631  "/", (int) getpid());
3632 #else
3633  snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
3634  "" /* trailing separator already present */ , (int) getpid());
3635 #endif
3636 
3637  fname = (const char *) fnametmp;
3638 
3639  fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
3640  if (fd != -1)
3641  stream = fdopen(fd, "w");
3642 
3643  if (fd == -1 || !stream)
3644  {
3645  pg_log_error("could not open temporary file \"%s\": %m", fname);
3646  error = true;
3647  }
3648  else
3649  {
3650  unsigned int ql = query_buf->len;
3651 
3652  /* force newline-termination of what we send to editor */
3653  if (ql > 0 && query_buf->data[ql - 1] != '\n')
3654  {
3655  appendPQExpBufferChar(query_buf, '\n');
3656  ql++;
3657  }
3658 
3659  if (fwrite(query_buf->data, 1, ql, stream) != ql)
3660  {
3661  pg_log_error("%s: %m", fname);
3662 
3663  if (fclose(stream) != 0)
3664  pg_log_error("%s: %m", fname);
3665 
3666  if (remove(fname) != 0)
3667  pg_log_error("%s: %m", fname);
3668 
3669  error = true;
3670  }
3671  else if (fclose(stream) != 0)
3672  {
3673  pg_log_error("%s: %m", fname);
3674  if (remove(fname) != 0)
3675  pg_log_error("%s: %m", fname);
3676  error = true;
3677  }
3678  }
3679  }
3680 
3681  if (!error && stat(fname, &before) != 0)
3682  {
3683  pg_log_error("%s: %m", fname);
3684  error = true;
3685  }
3686 
3687  /* call editor */
3688  if (!error)
3689  error = !editFile(fname, lineno);
3690 
3691  if (!error && stat(fname, &after) != 0)
3692  {
3693  pg_log_error("%s: %m", fname);
3694  error = true;
3695  }
3696 
3697  if (!error && before.st_mtime != after.st_mtime)
3698  {
3699  stream = fopen(fname, PG_BINARY_R);
3700  if (!stream)
3701  {
3702  pg_log_error("%s: %m", fname);
3703  error = true;
3704  }
3705  else
3706  {
3707  /* read file back into query_buf */
3708  char line[1024];
3709 
3710  resetPQExpBuffer(query_buf);
3711  while (fgets(line, sizeof(line), stream) != NULL)
3712  appendPQExpBufferStr(query_buf, line);
3713 
3714  if (ferror(stream))
3715  {
3716  pg_log_error("%s: %m", fname);
3717  error = true;
3718  }
3719  else if (edited)
3720  {
3721  *edited = true;
3722  }
3723 
3724  fclose(stream);
3725  }
3726  }
3727 
3728  /* remove temp file */
3729  if (!filename_arg)
3730  {
3731  if (remove(fname) == -1)
3732  {
3733  pg_log_error("%s: %m", fname);
3734  error = true;
3735  }
3736  }
3737 
3738  return !error;
3739 }
3740 
3741 
3742 
3743 /*
3744  * process_file
3745  *
3746  * Reads commands from filename and passes them to the main processing loop.
3747  * Handler for \i and \ir, but can be used for other things as well. Returns
3748  * MainLoop() error code.
3749  *
3750  * If use_relative_path is true and filename is not an absolute path, then open
3751  * the file from where the currently processed file (if any) is located.
3752  */
3753 int
3754 process_file(char *filename, bool use_relative_path)
3755 {
3756  FILE *fd;
3757  int result;
3758  char *oldfilename;
3759  char relpath[MAXPGPATH];
3760 
3761  if (!filename)
3762  {
3763  fd = stdin;
3764  filename = NULL;
3765  }
3766  else if (strcmp(filename, "-") != 0)
3767  {
3768  canonicalize_path(filename);
3769 
3770  /*
3771  * If we were asked to resolve the pathname relative to the location
3772  * of the currently executing script, and there is one, and this is a
3773  * relative pathname, then prepend all but the last pathname component
3774  * of the current script to this pathname.
3775  */
3776  if (use_relative_path && pset.inputfile &&
3777  !is_absolute_path(filename) && !has_drive_prefix(filename))
3778  {
3779  strlcpy(relpath, pset.inputfile, sizeof(relpath));
3780  get_parent_directory(relpath);
3781  join_path_components(relpath, relpath, filename);
3782  canonicalize_path(relpath);
3783 
3784  filename = relpath;
3785  }
3786 
3787  fd = fopen(filename, PG_BINARY_R);
3788 
3789  if (!fd)
3790  {
3791  pg_log_error("%s: %m", filename);
3792  return EXIT_FAILURE;
3793  }
3794  }
3795  else
3796  {
3797  fd = stdin;
3798  filename = "<stdin>"; /* for future error messages */
3799  }
3800 
3801  oldfilename = pset.inputfile;
3803 
3805 
3806  result = MainLoop(fd);
3807 
3808  if (fd != stdin)
3809  fclose(fd);
3810 
3811  pset.inputfile = oldfilename;
3812 
3814 
3815  return result;
3816 }
3817 
3818 
3819 
3820 static const char *
3822 {
3823  switch (in)
3824  {
3825  case PRINT_NOTHING:
3826  return "nothing";
3827  break;
3828  case PRINT_ALIGNED:
3829  return "aligned";
3830  break;
3831  case PRINT_ASCIIDOC:
3832  return "asciidoc";
3833  break;
3834  case PRINT_CSV:
3835  return "csv";
3836  break;
3837  case PRINT_HTML:
3838  return "html";
3839  break;
3840  case PRINT_LATEX:
3841  return "latex";
3842  break;
3843  case PRINT_LATEX_LONGTABLE:
3844  return "latex-longtable";
3845  break;
3846  case PRINT_TROFF_MS:
3847  return "troff-ms";
3848  break;
3849  case PRINT_UNALIGNED:
3850  return "unaligned";
3851  break;
3852  case PRINT_WRAPPED:
3853  return "wrapped";
3854  break;
3855  }
3856  return "unknown";
3857 }
3858 
3859 /*
3860  * Parse entered Unicode linestyle. If ok, update *linestyle and return
3861  * true, else return false.
3862  */
3863 static bool
3864 set_unicode_line_style(const char *value, size_t vallen,
3865  unicode_linestyle *linestyle)
3866 {
3867  if (pg_strncasecmp("single", value, vallen) == 0)
3868  *linestyle = UNICODE_LINESTYLE_SINGLE;
3869  else if (pg_strncasecmp("double", value, vallen) == 0)
3870  *linestyle = UNICODE_LINESTYLE_DOUBLE;
3871  else
3872  return false;
3873  return true;
3874 }
3875 
3876 static const char *
3878 {
3879  switch (linestyle)
3880  {
3882  return "single";
3883  break;
3885  return "double";
3886  break;
3887  }
3888  return "unknown";
3889 }
3890 
3891 /*
3892  * do_pset
3893  *
3894  * Performs the assignment "param = value", where value could be NULL;
3895  * for some params that has an effect such as inversion, for others
3896  * it does nothing.
3897  *
3898  * Adjusts the state of the formatting options at *popt. (In practice that
3899  * is always pset.popt, but maybe someday it could be different.)
3900  *
3901  * If successful and quiet is false, then invokes printPsetInfo() to report
3902  * the change.
3903  *
3904  * Returns true if successful, else false (eg for invalid param or value).
3905  */
3906 bool
3907 do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
3908 {
3909  size_t vallen = 0;
3910 
3911  Assert(param != NULL);
3912 
3913  if (value)
3914  vallen = strlen(value);
3915 
3916  /* set format */
3917  if (strcmp(param, "format") == 0)
3918  {
3919  static const struct fmt
3920  {
3921  const char *name;
3922  enum printFormat number;
3923  } formats[] =
3924  {
3925  /* remember to update error message below when adding more */
3926  {"aligned", PRINT_ALIGNED},
3927  {"asciidoc", PRINT_ASCIIDOC},
3928  {"csv", PRINT_CSV},
3929  {"html", PRINT_HTML},
3930  {"latex", PRINT_LATEX},
3931  {"troff-ms", PRINT_TROFF_MS},
3932  {"unaligned", PRINT_UNALIGNED},
3933  {"wrapped", PRINT_WRAPPED}
3934  };
3935 
3936  if (!value)
3937  ;
3938  else
3939  {
3940  int match_pos = -1;
3941 
3942  for (int i = 0; i < lengthof(formats); i++)
3943  {
3944  if (pg_strncasecmp(formats[i].name, value, vallen) == 0)
3945  {
3946  if (match_pos < 0)
3947  match_pos = i;
3948  else
3949  {
3950  pg_log_error("\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"",
3951  value,
3952  formats[match_pos].name, formats[i].name);
3953  return false;
3954  }
3955  }
3956  }
3957  if (match_pos >= 0)
3958  popt->topt.format = formats[match_pos].number;
3959  else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
3960  {
3961  /*
3962  * We must treat latex-longtable specially because latex is a
3963  * prefix of it; if both were in the table above, we'd think
3964  * "latex" is ambiguous.
3965  */
3967  }
3968  else
3969  {
3970  pg_log_error("\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped");
3971  return false;
3972  }
3973  }
3974  }
3975 
3976  /* set table line style */
3977  else if (strcmp(param, "linestyle") == 0)
3978  {
3979  if (!value)
3980  ;
3981  else if (pg_strncasecmp("ascii", value, vallen) == 0)
3982  popt->topt.line_style = &pg_asciiformat;
3983  else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
3985  else if (pg_strncasecmp("unicode", value, vallen) == 0)
3986  popt->topt.line_style = &pg_utf8format;
3987  else
3988  {
3989  pg_log_error("\\pset: allowed line styles are ascii, old-ascii, unicode");
3990  return false;
3991  }
3992  }
3993 
3994  /* set unicode border line style */
3995  else if (strcmp(param, "unicode_border_linestyle") == 0)
3996  {
3997  if (!value)
3998  ;
3999  else if (set_unicode_line_style(value, vallen,
4001  refresh_utf8format(&(popt->topt));
4002  else
4003  {
4004  pg_log_error("\\pset: allowed Unicode border line styles are single, double");
4005  return false;
4006  }
4007  }
4008 
4009  /* set unicode column line style */
4010  else if (strcmp(param, "unicode_column_linestyle") == 0)
4011  {
4012  if (!value)
4013  ;
4014  else if (set_unicode_line_style(value, vallen,
4016  refresh_utf8format(&(popt->topt));
4017  else
4018  {
4019  pg_log_error("\\pset: allowed Unicode column line styles are single, double");
4020  return false;
4021  }
4022  }
4023 
4024  /* set unicode header line style */
4025  else if (strcmp(param, "unicode_header_linestyle") == 0)
4026  {
4027  if (!value)
4028  ;
4029  else if (set_unicode_line_style(value, vallen,
4031  refresh_utf8format(&(popt->topt));
4032  else
4033  {
4034  pg_log_error("\\pset: allowed Unicode header line styles are single, double");
4035  return false;
4036  }
4037  }
4038 
4039  /* set border style/width */
4040  else if (strcmp(param, "border") == 0)
4041  {
4042  if (value)
4043  popt->topt.border = atoi(value);
4044  }
4045 
4046  /* set expanded/vertical mode */
4047  else if (strcmp(param, "x") == 0 ||
4048  strcmp(param, "expanded") == 0 ||
4049  strcmp(param, "vertical") == 0)
4050  {
4051  if (value && pg_strcasecmp(value, "auto") == 0)
4052  popt->topt.expanded = 2;
4053  else if (value)
4054  {
4055  bool on_off;
4056 
4057  if (ParseVariableBool(value, NULL, &on_off))
4058  popt->topt.expanded = on_off ? 1 : 0;
4059  else
4060  {
4061  PsqlVarEnumError(param, value, "on, off, auto");
4062  return false;
4063  }
4064  }
4065  else
4066  popt->topt.expanded = !popt->topt.expanded;
4067  }
4068 
4069  /* field separator for CSV format */
4070  else if (strcmp(param, "csv_fieldsep") == 0)
4071  {
4072  if (value)
4073  {
4074  /* CSV separator has to be a one-byte character */
4075  if (strlen(value) != 1)
4076  {
4077  pg_log_error("\\pset: csv_fieldsep must be a single one-byte character");
4078  return false;
4079  }
4080  if (value[0] == '"' || value[0] == '\n' || value[0] == '\r')
4081  {
4082  pg_log_error("\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return");
4083  return false;
4084  }
4085  popt->topt.csvFieldSep[0] = value[0];
4086  }
4087  }
4088 
4089  /* locale-aware numeric output */
4090  else if (strcmp(param, "numericlocale") == 0)
4091  {
4092  if (value)
4093  return ParseVariableBool(value, param, &popt->topt.numericLocale);
4094  else
4095  popt->topt.numericLocale = !popt->topt.numericLocale;
4096  }
4097 
4098  /* null display */
4099  else if (strcmp(param, "null") == 0)
4100  {
4101  if (value)
4102  {
4103  free(popt->nullPrint);
4104  popt->nullPrint = pg_strdup(value);
4105  }
4106  }
4107 
4108  /* field separator for unaligned text */
4109  else if (strcmp(param, "fieldsep") == 0)
4110  {
4111  if (value)
4112  {
4113  free(popt->topt.fieldSep.separator);
4114  popt->topt.fieldSep.separator = pg_strdup(value);
4115  popt->topt.fieldSep.separator_zero = false;
4116  }
4117  }
4118 
4119  else if (strcmp(param, "fieldsep_zero") == 0)
4120  {
4121  free(popt->topt.fieldSep.separator);
4122  popt->topt.fieldSep.separator = NULL;
4123  popt->topt.fieldSep.separator_zero = true;
4124  }
4125 
4126  /* record separator for unaligned text */
4127  else if (strcmp(param, "recordsep") == 0)
4128  {
4129  if (value)
4130  {
4131  free(popt->topt.recordSep.separator);
4132  popt->topt.recordSep.separator = pg_strdup(value);
4133  popt->topt.recordSep.separator_zero = false;
4134  }
4135  }
4136 
4137  else if (strcmp(param, "recordsep_zero") == 0)
4138  {
4139  free(popt->topt.recordSep.separator);
4140  popt->topt.recordSep.separator = NULL;
4141  popt->topt.recordSep.separator_zero = true;
4142  }
4143 
4144  /* toggle between full and tuples-only format */
4145  else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
4146  {
4147  if (value)
4148  return ParseVariableBool(value, param, &popt->topt.tuples_only);
4149  else
4150  popt->topt.tuples_only = !popt->topt.tuples_only;
4151  }
4152 
4153  /* set title override */
4154  else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
4155  {
4156  free(popt->title);
4157  if (!value)
4158  popt->title = NULL;
4159  else
4160  popt->title = pg_strdup(value);
4161  }
4162 
4163  /* set HTML table tag options */
4164  else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
4165  {
4166  free(popt->topt.tableAttr);
4167  if (!value)
4168  popt->topt.tableAttr = NULL;
4169  else
4170  popt->topt.tableAttr = pg_strdup(value);
4171  }
4172 
4173  /* toggle use of pager */
4174  else if (strcmp(param, "pager") == 0)
4175  {
4176  if (value && pg_strcasecmp(value, "always") == 0)
4177  popt->topt.pager = 2;
4178  else if (value)
4179  {
4180  bool on_off;
4181 
4182  if (!ParseVariableBool(value, NULL, &on_off))
4183  {
4184  PsqlVarEnumError(param, value, "on, off, always");
4185  return false;
4186  }
4187  popt->topt.pager = on_off ? 1 : 0;
4188  }
4189  else if (popt->topt.pager == 1)
4190  popt->topt.pager = 0;
4191  else
4192  popt->topt.pager = 1;
4193  }
4194 
4195  /* set minimum lines for pager use */
4196  else if (strcmp(param, "pager_min_lines") == 0)
4197  {
4198  if (value)
4199  popt->topt.pager_min_lines = atoi(value);
4200  }
4201 
4202  /* disable "(x rows)" footer */
4203  else if (strcmp(param, "footer") == 0)
4204  {
4205  if (value)
4206  return ParseVariableBool(value, param, &popt->topt.default_footer);
4207  else
4208  popt->topt.default_footer = !popt->topt.default_footer;
4209  }
4210 
4211  /* set border style/width */
4212  else if (strcmp(param, "columns") == 0)
4213  {
4214  if (value)
4215  popt->topt.columns = atoi(value);
4216  }
4217  else
4218  {
4219  pg_log_error("\\pset: unknown option: %s", param);
4220  return false;
4221  }
4222 
4223  if (!quiet)
4224  printPsetInfo(param, &pset.popt);
4225 
4226  return true;
4227 }
4228 
4229 /*
4230  * printPsetInfo: print the state of the "param" formatting parameter in popt.
4231  */
4232 static bool
4233 printPsetInfo(const char *param, printQueryOpt *popt)
4234 {
4235  Assert(param != NULL);
4236 
4237  /* show border style/width */
4238  if (strcmp(param, "border") == 0)
4239  printf(_("Border style is %d.\n"), popt->topt.border);
4240 
4241  /* show the target width for the wrapped format */
4242  else if (strcmp(param, "columns") == 0)
4243  {
4244  if (!popt->topt.columns)
4245  printf(_("Target width is unset.\n"));
4246  else
4247  printf(_("Target width is %d.\n"), popt->topt.columns);
4248  }
4249 
4250  /* show expanded/vertical mode */
4251  else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
4252  {
4253  if (popt->topt.expanded == 1)
4254  printf(_("Expanded display is on.\n"));
4255  else if (popt->topt.expanded == 2)
4256  printf(_("Expanded display is used automatically.\n"));
4257  else
4258  printf(_("Expanded display is off.\n"));
4259  }
4260 
4261  /* show field separator for CSV format */
4262  else if (strcmp(param, "csv_fieldsep") == 0)
4263  {
4264  printf(_("Field separator for CSV is \"%s\".\n"),
4265  popt->topt.csvFieldSep);
4266  }
4267 
4268  /* show field separator for unaligned text */
4269  else if (strcmp(param, "fieldsep") == 0)
4270  {
4271  if (popt->topt.fieldSep.separator_zero)
4272  printf(_("Field separator is zero byte.\n"));
4273  else
4274  printf(_("Field separator is \"%s\".\n"),
4275  popt->topt.fieldSep.separator);
4276  }
4277 
4278  else if (strcmp(param, "fieldsep_zero") == 0)
4279  {
4280  printf(_("Field separator is zero byte.\n"));
4281  }
4282 
4283  /* show disable "(x rows)" footer */
4284  else if (strcmp(param, "footer") == 0)
4285  {
4286  if (popt->topt.default_footer)
4287  printf(_("Default footer is on.\n"));
4288  else
4289  printf(_("Default footer is off.\n"));
4290  }
4291 
4292  /* show format */
4293  else if (strcmp(param, "format") == 0)
4294  {
4295  printf(_("Output format is %s.\n"), _align2string(popt->topt.format));
4296  }
4297 
4298  /* show table line style */
4299  else if (strcmp(param, "linestyle") == 0)
4300  {
4301  printf(_("Line style is %s.\n"),
4302  get_line_style(&popt->topt)->name);
4303  }
4304 
4305  /* show null display */
4306  else if (strcmp(param, "null") == 0)
4307  {
4308  printf(_("Null display is \"%s\".\n"),
4309  popt->nullPrint ? popt->nullPrint : "");
4310  }
4311 
4312  /* show locale-aware numeric output */
4313  else if (strcmp(param, "numericlocale") == 0)
4314  {
4315  if (popt->topt.numericLocale)
4316  printf(_("Locale-adjusted numeric output is on.\n"));
4317  else
4318  printf(_("Locale-adjusted numeric output is off.\n"));
4319  }
4320 
4321  /* show toggle use of pager */
4322  else if (strcmp(param, "pager") == 0)
4323  {
4324  if (popt->topt.pager == 1)
4325  printf(_("Pager is used for long output.\n"));
4326  else if (popt->topt.pager == 2)
4327  printf(_("Pager is always used.\n"));
4328  else
4329  printf(_("Pager usage is off.\n"));
4330  }
4331 
4332  /* show minimum lines for pager use */
4333  else if (strcmp(param, "pager_min_lines") == 0)
4334  {
4335  printf(ngettext("Pager won't be used for less than %d line.\n",
4336  "Pager won't be used for less than %d lines.\n",
4337  popt->topt.pager_min_lines),
4338  popt->topt.pager_min_lines);
4339  }
4340 
4341  /* show record separator for unaligned text */
4342  else if (strcmp(param, "recordsep") == 0)
4343  {
4344  if (popt->topt.recordSep.separator_zero)
4345  printf(_("Record separator is zero byte.\n"));
4346  else if (strcmp(popt->topt.recordSep.separator, "\n") == 0)
4347  printf(_("Record separator is <newline>.\n"));
4348  else
4349  printf(_("Record separator is \"%s\".\n"),
4350  popt->topt.recordSep.separator);
4351  }
4352 
4353  else if (strcmp(param, "recordsep_zero") == 0)
4354  {
4355  printf(_("Record separator is zero byte.\n"));
4356  }
4357 
4358  /* show HTML table tag options */
4359  else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
4360  {
4361  if (popt->topt.tableAttr)
4362  printf(_("Table attributes are \"%s\".\n"),
4363  popt->topt.tableAttr);
4364  else
4365  printf(_("Table attributes unset.\n"));
4366  }
4367 
4368  /* show title override */
4369  else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
4370  {
4371  if (popt->title)
4372  printf(_("Title is \"%s\".\n"), popt->title);
4373  else
4374  printf(_("Title is unset.\n"));
4375  }
4376 
4377  /* show toggle between full and tuples-only format */
4378  else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
4379  {
4380  if (popt->topt.tuples_only)
4381  printf(_("Tuples only is on.\n"));
4382  else
4383  printf(_("Tuples only is off.\n"));
4384  }
4385 
4386  /* Unicode style formatting */
4387  else if (strcmp(param, "unicode_border_linestyle") == 0)
4388  {
4389  printf(_("Unicode border line style is \"%s\".\n"),
4391  }
4392 
4393  else if (strcmp(param, "unicode_column_linestyle") == 0)
4394  {
4395  printf(_("Unicode column line style is \"%s\".\n"),
4397  }
4398 
4399  else if (strcmp(param, "unicode_header_linestyle") == 0)
4400  {
4401  printf(_("Unicode header line style is \"%s\".\n"),
4403  }
4404 
4405  else
4406  {
4407  pg_log_error("\\pset: unknown option: %s", param);
4408  return false;
4409  }
4410 
4411  return true;
4412 }
4413 
4414 /*
4415  * savePsetInfo: make a malloc'd copy of the data in *popt.
4416  *
4417  * Possibly this should be somewhere else, but it's a bit specific to psql.
4418  */
4419 printQueryOpt *
4421 {
4422  printQueryOpt *save;
4423 
4424  save = (printQueryOpt *) pg_malloc(sizeof(printQueryOpt));
4425 
4426  /* Flat-copy all the scalar fields, then duplicate sub-structures. */
4427  memcpy(save, popt, sizeof(printQueryOpt));
4428 
4429  /* topt.line_style points to const data that need not be duplicated */
4430  if (popt->topt.fieldSep.separator)
4432  if (popt->topt.recordSep.separator)
4434  if (popt->topt.tableAttr)
4435  save->topt.tableAttr = pg_strdup(popt->topt.tableAttr);
4436  if (popt->nullPrint)
4437  save->nullPrint = pg_strdup(popt->nullPrint);
4438  if (popt->title)
4439  save->title = pg_strdup(popt->title);
4440 
4441  /*
4442  * footers and translate_columns are never set in psql's print settings,
4443  * so we needn't write code to duplicate them.
4444  */
4445  Assert(popt->footers == NULL);
4446  Assert(popt->translate_columns == NULL);
4447 
4448  return save;
4449 }
4450 
4451 /*
4452  * restorePsetInfo: restore *popt from the previously-saved copy *save,
4453  * then free *save.
4454  */
4455 void
4457 {
4458  /* Free all the old data we're about to overwrite the pointers to. */
4459 
4460  /* topt.line_style points to const data that need not be duplicated */
4461  if (popt->topt.fieldSep.separator)
4462  free(popt->topt.fieldSep.separator);
4463  if (popt->topt.recordSep.separator)
4464  free(popt->topt.recordSep.separator);
4465  if (popt->topt.tableAttr)
4466  free(popt->topt.tableAttr);
4467  if (popt->nullPrint)
4468  free(popt->nullPrint);
4469  if (popt->title)
4470  free(popt->title);
4471 
4472  /*
4473  * footers and translate_columns are never set in psql's print settings,
4474  * so we needn't write code to duplicate them.
4475  */
4476  Assert(popt->footers == NULL);
4477  Assert(popt->translate_columns == NULL);
4478 
4479  /* Now we may flat-copy all the fields, including pointers. */
4480  memcpy(popt, save, sizeof(printQueryOpt));
4481 
4482  /* Lastly, free "save" ... but its sub-structures now belong to popt. */
4483  free(save);
4484 }
4485 
4486 static const char *
4488 {
4489  return val ? "on" : "off";
4490 }
4491 
4492 
4493 static char *
4495 {
4496  char *ret = pg_malloc(strlen(str) * 2 + 3);
4497  char *r = ret;
4498 
4499  *r++ = '\'';
4500 
4501  for (; *str; str++)
4502  {
4503  if (*str == '\n')
4504  {
4505  *r++ = '\\';
4506  *r++ = 'n';
4507  }
4508  else if (*str == '\'')
4509  {
4510  *r++ = '\\';
4511  *r++ = '\'';
4512  }
4513  else
4514  *r++ = *str;
4515  }
4516 
4517  *r++ = '\'';
4518  *r = '\0';
4519 
4520  return ret;
4521 }
4522 
4523 
4524 /*
4525  * Return a malloc'ed string for the \pset value.
4526  *
4527  * Note that for some string parameters, print.c distinguishes between unset
4528  * and empty string, but for others it doesn't. This function should produce
4529  * output that produces the correct setting when fed back into \pset.
4530  */
4531 static char *
4532 pset_value_string(const char *param, printQueryOpt *popt)
4533 {
4534  Assert(param != NULL);
4535 
4536  if (strcmp(param, "border") == 0)
4537  return psprintf("%d", popt->topt.border);
4538  else if (strcmp(param, "columns") == 0)
4539  return psprintf("%d", popt->topt.columns);
4540  else if (strcmp(param, "csv_fieldsep") == 0)
4541  return pset_quoted_string(popt->topt.csvFieldSep);
4542  else if (strcmp(param, "expanded") == 0)
4543  return pstrdup(popt->topt.expanded == 2
4544  ? "auto"
4545  : pset_bool_string(popt->topt.expanded));
4546  else if (strcmp(param, "fieldsep") == 0)
4548  ? popt->topt.fieldSep.separator
4549  : "");
4550  else if (strcmp(param, "fieldsep_zero") == 0)
4552  else if (strcmp(param, "footer") == 0)
4554  else if (strcmp(param, "format") == 0)
4555  return psprintf("%s", _align2string(popt->topt.format));
4556  else if (strcmp(param, "linestyle") == 0)
4557  return psprintf("%s", get_line_style(&popt->topt)->name);
4558  else if (strcmp(param, "null") == 0)
4559  return pset_quoted_string(popt->nullPrint
4560  ? popt->nullPrint
4561  : "");
4562  else if (strcmp(param, "numericlocale") == 0)
4563  return pstrdup(pset_bool_string(popt->topt.numericLocale));
4564  else if (strcmp(param, "pager") == 0)
4565  return psprintf("%d", popt->topt.pager);
4566  else if (strcmp(param, "pager_min_lines") == 0)
4567  return psprintf("%d", popt->topt.pager_min_lines);
4568  else if (strcmp(param, "recordsep") == 0)
4570  ? popt->topt.recordSep.separator
4571  : "");
4572  else if (strcmp(param, "recordsep_zero") == 0)
4574  else if (strcmp(param, "tableattr") == 0)
4575  return popt->topt.tableAttr ? pset_quoted_string(popt->topt.tableAttr) : pstrdup("");
4576  else if (strcmp(param, "title") == 0)
4577  return popt->title ? pset_quoted_string(popt->title) : pstrdup("");
4578  else if (strcmp(param, "tuples_only") == 0)
4579  return pstrdup(pset_bool_string(popt->topt.tuples_only));
4580  else if (strcmp(param, "unicode_border_linestyle") == 0)
4582  else if (strcmp(param, "unicode_column_linestyle") == 0)
4584  else if (strcmp(param, "unicode_header_linestyle") == 0)
4586  else
4587  return pstrdup("ERROR");
4588 }
4589 
4590 
4591 
4592 #ifndef WIN32
4593 #define DEFAULT_SHELL "/bin/sh"
4594 #else
4595 /*
4596  * CMD.EXE is in different places in different Win32 releases so we
4597  * have to rely on the path to find it.
4598  */
4599 #define DEFAULT_SHELL "cmd.exe"
4600 #endif
4601 
4602 static bool
4603 do_shell(const char *command)
4604 {
4605  int result;
4606 
4607  if (!command)
4608  {
4609  char *sys;
4610  const char *shellName;
4611 
4612  shellName = getenv("SHELL");
4613 #ifdef WIN32
4614  if (shellName == NULL)
4615  shellName = getenv("COMSPEC");
4616 #endif
4617  if (shellName == NULL)
4618  shellName = DEFAULT_SHELL;
4619 
4620  /* See EDITOR handling comment for an explanation */
4621 #ifndef WIN32
4622  sys = psprintf("exec %s", shellName);
4623 #else
4624  sys = psprintf("\"%s\"", shellName);
4625 #endif
4626  result = system(sys);
4627  free(sys);
4628  }
4629  else
4630  result = system(command);
4631 
4632  if (result == 127 || result == -1)
4633  {
4634  pg_log_error("\\!: failed");
4635  return false;
4636  }
4637  return true;
4638 }
4639 
4640 /*
4641  * do_watch -- handler for \watch
4642  *
4643  * We break this out of exec_command to avoid having to plaster "volatile"
4644  * onto a bunch of exec_command's variables to silence stupider compilers.
4645  */
4646 static bool
4647 do_watch(PQExpBuffer query_buf, double sleep)
4648 {
4649  long sleep_ms = (long) (sleep * 1000);
4650  printQueryOpt myopt = pset.popt;
4651  const char *strftime_fmt;
4652  const char *user_title;
4653  char *title;
4654  int title_len;
4655  int res = 0;
4656 
4657  if (!query_buf || query_buf->len <= 0)
4658  {
4659  pg_log_error("\\watch cannot be used with an empty query");
4660  return false;
4661  }
4662 
4663  /*
4664  * Choose format for timestamps. We might eventually make this a \pset
4665  * option. In the meantime, using a variable for the format suppresses
4666  * overly-anal-retentive gcc warnings about %c being Y2K sensitive.
4667  */
4668  strftime_fmt = "%c";
4669 
4670  /*
4671  * Set up rendering options, in particular, disable the pager, because
4672  * nobody wants to be prompted while watching the output of 'watch'.
4673  */
4674  myopt.topt.pager = 0;
4675 
4676  /*
4677  * If there's a title in the user configuration, make sure we have room
4678  * for it in the title buffer. Allow 128 bytes for the timestamp plus 128
4679  * bytes for the rest.
4680  */
4681  user_title = myopt.title;
4682  title_len = (user_title ? strlen(user_title) : 0) + 256;
4683  title = pg_malloc(title_len);
4684 
4685  for (;;)
4686  {
4687  time_t timer;
4688  char timebuf[128];
4689  long i;
4690 
4691  /*
4692  * Prepare title for output. Note that we intentionally include a
4693  * newline at the end of the title; this is somewhat historical but it
4694  * makes for reasonably nicely formatted output in simple cases.
4695  */
4696  timer = time(NULL);
4697  strftime(timebuf, sizeof(timebuf), strftime_fmt, localtime(&timer));
4698 
4699  if (user_title)
4700  snprintf(title, title_len, _("%s\t%s (every %gs)\n"),
4701  user_title, timebuf, sleep);
4702  else
4703  snprintf(title, title_len, _("%s (every %gs)\n"),
4704  timebuf, sleep);
4705  myopt.title = title;
4706 
4707  /* Run the query and print out the results */
4708  res = PSQLexecWatch(query_buf->data, &myopt);
4709 
4710  /*
4711  * PSQLexecWatch handles the case where we can no longer repeat the
4712  * query, and returns 0 or -1.
4713  */
4714  if (res <= 0)
4715  break;
4716 
4717  /*
4718  * Set up cancellation of 'watch' via SIGINT. We redo this each time
4719  * through the loop since it's conceivable something inside
4720  * PSQLexecWatch could change sigint_interrupt_jmp.
4721  */
4722  if (sigsetjmp(sigint_interrupt_jmp, 1) != 0)
4723  break;
4724 
4725  /*
4726  * Enable 'watch' cancellations and wait a while before running the
4727  * query again. Break the sleep into short intervals (at most 1s)
4728  * since pg_usleep isn't interruptible on some platforms.
4729  */
4730  sigint_interrupt_enabled = true;
4731  i = sleep_ms;
4732  while (i > 0)
4733  {
4734  long s = Min(i, 1000L);
4735 
4736  pg_usleep(s * 1000L);
4737  if (cancel_pressed)
4738  break;
4739  i -= s;
4740  }
4741  sigint_interrupt_enabled = false;
4742  }
4743 
4744  pg_free(title);
4745  return (res >= 0);
4746 }
4747 
4748 /*
4749  * a little code borrowed from PSQLexec() to manage ECHO_HIDDEN output.
4750  * returns true unless we have ECHO_HIDDEN_NOEXEC.
4751  */
4752 static bool
4753 echo_hidden_command(const char *query)
4754 {
4756  {
4757  printf(_("********* QUERY **********\n"
4758  "%s\n"
4759  "**************************\n\n"), query);
4760  fflush(stdout);
4761  if (pset.logfile)
4762  {
4764  _("********* QUERY **********\n"
4765  "%s\n"
4766  "**************************\n\n"), query);
4767  fflush(pset.logfile);
4768  }
4769 
4771  return false;
4772  }
4773  return true;
4774 }
4775 
4776 /*
4777  * Look up the object identified by obj_type and desc. If successful,
4778  * store its OID in *obj_oid and return true, else return false.
4779  *
4780  * Note that we'll fail if the object doesn't exist OR if there are multiple
4781  * matching candidates OR if there's something syntactically wrong with the
4782  * object description; unfortunately it can be hard to tell the difference.
4783  */
4784 static bool
4785 lookup_object_oid(EditableObjectType obj_type, const char *desc,
4786  Oid *obj_oid)
4787 {
4788  bool result = true;
4789  PQExpBuffer query = createPQExpBuffer();
4790  PGresult *res;
4791 
4792  switch (obj_type)
4793  {
4794  case EditableFunction:
4795 
4796  /*
4797  * We have a function description, e.g. "x" or "x(int)". Issue a
4798  * query to retrieve the function's OID using a cast to regproc or
4799  * regprocedure (as appropriate).
4800  */
4801  appendPQExpBufferStr(query, "SELECT ");
4802  appendStringLiteralConn(query, desc, pset.db);
4803  appendPQExpBuffer(query, "::pg_catalog.%s::pg_catalog.oid",
4804  strchr(desc, '(') ? "regprocedure" : "regproc");
4805  break;
4806 
4807  case EditableView:
4808 
4809  /*
4810  * Convert view name (possibly schema-qualified) to OID. Note:
4811  * this code doesn't check if the relation is actually a view.
4812  * We'll detect that in get_create_object_cmd().
4813  */
4814  appendPQExpBufferStr(query, "SELECT ");
4815  appendStringLiteralConn(query, desc, pset.db);
4816  appendPQExpBufferStr(query, "::pg_catalog.regclass::pg_catalog.oid");
4817  break;
4818  }
4819 
4820  if (!echo_hidden_command(query->data))
4821  {
4822  destroyPQExpBuffer(query);
4823  return false;
4824  }
4825  res = PQexec(pset.db, query->data);
4826  if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
4827  *obj_oid = atooid(PQgetvalue(res, 0, 0));
4828  else
4829  {
4830  minimal_error_message(res);
4831  result = false;
4832  }
4833 
4834  PQclear(res);
4835  destroyPQExpBuffer(query);
4836 
4837  return result;
4838 }
4839 
4840 /*
4841  * Construct a "CREATE OR REPLACE ..." command that describes the specified
4842  * database object. If successful, the result is stored in buf.
4843  */
4844 static bool
4846  PQExpBuffer buf)
4847 {
4848  bool result = true;
4849  PQExpBuffer query = createPQExpBuffer();
4850  PGresult *res;
4851 
4852  switch (obj_type)
4853  {
4854  case EditableFunction:
4855  printfPQExpBuffer(query,
4856  "SELECT pg_catalog.pg_get_functiondef(%u)",
4857  oid);
4858  break;
4859 
4860  case EditableView:
4861 
4862  /*
4863  * pg_get_viewdef() just prints the query, so we must prepend
4864  * CREATE for ourselves. We must fully qualify the view name to
4865  * ensure the right view gets replaced. Also, check relation kind
4866  * to be sure it's a view.
4867  *
4868  * Starting with 9.2, views may have reloptions (security_barrier)
4869  * and from 9.4 onwards they may also have WITH [LOCAL|CASCADED]
4870  * CHECK OPTION. These are not part of the view definition
4871  * returned by pg_get_viewdef() and so need to be retrieved
4872  * separately. Materialized views (introduced in 9.3) may have
4873  * arbitrary storage parameter reloptions.
4874  */
4875  if (pset.sversion >= 90400)
4876  {
4877  printfPQExpBuffer(query,
4878  "SELECT nspname, relname, relkind, "
4879  "pg_catalog.pg_get_viewdef(c.oid, true), "
4880  "pg_catalog.array_remove(pg_catalog.array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
4881  "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
4882  "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
4883  "FROM pg_catalog.pg_class c "
4884  "LEFT JOIN pg_catalog.pg_namespace n "
4885  "ON c.relnamespace = n.oid WHERE c.oid = %u",
4886  oid);
4887  }
4888  else if (pset.sversion >= 90200)
4889  {
4890  printfPQExpBuffer(query,
4891  "SELECT nspname, relname, relkind, "
4892  "pg_catalog.pg_get_viewdef(c.oid, true), "
4893  "c.reloptions AS reloptions, "
4894  "NULL AS checkoption "
4895  "FROM pg_catalog.pg_class c "
4896  "LEFT JOIN pg_catalog.pg_namespace n "
4897  "ON c.relnamespace = n.oid WHERE c.oid = %u",
4898  oid);
4899  }
4900  else
4901  {
4902  printfPQExpBuffer(query,
4903  "SELECT nspname, relname, relkind, "
4904  "pg_catalog.pg_get_viewdef(c.oid, true), "
4905  "NULL AS reloptions, "
4906  "NULL AS checkoption "
4907  "FROM pg_catalog.pg_class c "
4908  "LEFT JOIN pg_catalog.pg_namespace n "
4909  "ON c.relnamespace = n.oid WHERE c.oid = %u",
4910  oid);
4911  }
4912  break;
4913  }
4914 
4915  if (!echo_hidden_command(query->data))
4916  {
4917  destroyPQExpBuffer(query);
4918  return false;
4919  }
4920  res = PQexec(pset.db, query->data);
4921  if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
4922  {
4923  resetPQExpBuffer(buf);
4924  switch (obj_type)
4925  {
4926  case EditableFunction:
4927  appendPQExpBufferStr(buf, PQgetvalue(res, 0, 0));
4928  break;
4929 
4930  case EditableView:
4931  {
4932  char *nspname = PQgetvalue(res, 0, 0);
4933  char *relname = PQgetvalue(res, 0, 1);
4934  char *relkind = PQgetvalue(res, 0, 2);
4935  char *viewdef = PQgetvalue(res, 0, 3);
4936  char *reloptions = PQgetvalue(res, 0, 4);
4937  char *checkoption = PQgetvalue(res, 0, 5);
4938 
4939  /*
4940  * If the backend ever supports CREATE OR REPLACE
4941  * MATERIALIZED VIEW, allow that here; but as of today it
4942  * does not, so editing a matview definition in this way
4943  * is impossible.
4944  */
4945  switch (relkind[0])
4946  {
4947 #ifdef NOT_USED
4948  case RELKIND_MATVIEW:
4949  appendPQExpBufferStr(buf, "CREATE OR REPLACE MATERIALIZED VIEW ");
4950  break;
4951 #endif
4952  case RELKIND_VIEW:
4953  appendPQExpBufferStr(buf, "CREATE OR REPLACE VIEW ");
4954  break;
4955  default:
4956  pg_log_error("\"%s.%s\" is not a view",
4957  nspname, relname);
4958  result = false;
4959  break;
4960  }
4961  appendPQExpBuffer(buf, "%s.", fmtId(nspname));
4962  appendPQExpBufferStr(buf, fmtId(relname));
4963 
4964  /* reloptions, if not an empty array "{}" */
4965  if (reloptions != NULL && strlen(reloptions) > 2)
4966  {
4967  appendPQExpBufferStr(buf, "\n WITH (");
4968  if (!appendReloptionsArray(buf, reloptions, "",
4969  pset.encoding,
4970  standard_strings()))
4971  {
4972  pg_log_error("could not parse reloptions array");
4973  result = false;
4974  }
4975  appendPQExpBufferChar(buf, ')');
4976  }
4977 
4978  /* View definition from pg_get_viewdef (a SELECT query) */
4979  appendPQExpBuffer(buf, " AS\n%s", viewdef);
4980 
4981  /* Get rid of the semicolon that pg_get_viewdef appends */
4982  if (buf->len > 0 && buf->data[buf->len - 1] == ';')
4983  buf->data[--(buf->len)] = '\0';
4984 
4985  /* WITH [LOCAL|CASCADED] CHECK OPTION */
4986  if (checkoption && checkoption[0] != '\0')
4987  appendPQExpBuffer(buf, "\n WITH %s CHECK OPTION",
4988  checkoption);
4989  }
4990  break;
4991  }
4992  /* Make sure result ends with a newline */
4993  if (buf->len > 0 && buf->data[buf->len - 1] != '\n')
4994  appendPQExpBufferChar(buf, '\n');
4995  }
4996  else
4997  {
4998  minimal_error_message(res);
4999  result = false;
5000  }
5001 
5002  PQclear(res);
5003  destroyPQExpBuffer(query);
5004 
5005  return result;
5006 }
5007 
5008 /*
5009  * If the given argument of \ef or \ev ends with a line number, delete the line
5010  * number from the argument string and return it as an integer. (We need
5011  * this kluge because we're too lazy to parse \ef's function or \ev's view
5012  * argument carefully --- we just slop it up in OT_WHOLE_LINE mode.)
5013  *
5014  * Returns -1 if no line number is present, 0 on error, or a positive value
5015  * on success.
5016  */
5017 static int
5019 {
5020  char *c;
5021  int lineno;
5022 
5023  if (!obj || obj[0] == '\0')
5024  return -1;
5025 
5026  c = obj + strlen(obj) - 1;
5027 
5028  /*
5029  * This business of parsing backwards is dangerous as can be in a
5030  * multibyte environment: there is no reason to believe that we are
5031  * looking at the first byte of a character, nor are we necessarily
5032  * working in a "safe" encoding. Fortunately the bitpatterns we are
5033  * looking for are unlikely to occur as non-first bytes, but beware of
5034  * trying to expand the set of cases that can be recognized. We must
5035  * guard the <ctype.h> macros by using isascii() first, too.
5036  */
5037 
5038  /* skip trailing whitespace */
5039  while (c > obj && isascii((unsigned char) *c) && isspace((unsigned char) *c))
5040  c--;
5041 
5042  /* must have a digit as last non-space char */
5043  if (c == obj || !isascii((unsigned char) *c) || !isdigit((unsigned char) *c))
5044  return -1;
5045 
5046  /* find start of digit string */
5047  while (c > obj && isascii((unsigned char) *c) && isdigit((unsigned char) *c))
5048  c--;
5049 
5050  /* digits must be separated from object name by space or closing paren */
5051  /* notice also that we are not allowing an empty object name ... */
5052  if (c == obj || !isascii((unsigned char) *c) ||
5053  !(isspace((unsigned char) *c) || *c == ')'))
5054  return -1;
5055 
5056  /* parse digit string */
5057  c++;
5058  lineno = atoi(c);
5059  if (lineno < 1)
5060  {
5061  pg_log_error("invalid line number: %s", c);
5062  return 0;
5063  }
5064 
5065  /* strip digit string from object name */
5066  *c = '\0';
5067 
5068  return lineno;
5069 }
5070 
5071 /*
5072  * Count number of lines in the buffer.
5073  * This is used to test if pager is needed or not.
5074  */
5075 static int
5077 {
5078  int lineno = 0;
5079  const char *lines = buf->data;
5080 
5081  while (*lines != '\0')
5082  {
5083  lineno++;
5084  /* find start of next line */
5085  lines = strchr(lines, '\n');
5086  if (!lines)
5087  break;
5088  lines++;
5089  }
5090 
5091  return lineno;
5092 }
5093 
5094 /*
5095  * Write text at *lines to output with line numbers.
5096  *
5097  * If header_keyword isn't NULL, then line 1 should be the first line beginning
5098  * with header_keyword; lines before that are unnumbered.
5099  *
5100  * Caution: this scribbles on *lines.
5101  */
5102 static void
5103 print_with_linenumbers(FILE *output, char *lines,
5104  const char *header_keyword)
5105 {
5106  bool in_header = (header_keyword != NULL);
5107  size_t header_sz = in_header ? strlen(header_keyword) : 0;
5108  int lineno = 0;
5109 
5110  while (*lines != '\0')
5111  {
5112  char *eol;
5113 
5114  if (in_header && strncmp(lines, header_keyword, header_sz) == 0)
5115  in_header = false;
5116 
5117  /* increment lineno only for body's lines */
5118  if (!in_header)
5119  lineno++;
5120 
5121  /* find and mark end of current line */
5122  eol = strchr(lines, '\n');
5123  if (eol != NULL)
5124  *eol = '\0';
5125 
5126  /* show current line as appropriate */
5127  if (in_header)
5128  fprintf(output, " %s\n", lines);
5129  else
5130  fprintf(output, "%-7d %s\n", lineno, lines);
5131 
5132  /* advance to next line, if any */
5133  if (eol == NULL)
5134  break;
5135  lines = ++eol;
5136  }
5137 }
5138 
5139 /*
5140  * Report just the primary error; this is to avoid cluttering the output
5141  * with, for instance, a redisplay of the internally generated query
5142  */
5143 static void
5145 {
5146  PQExpBuffer msg;
5147  const char *fld;
5148 
5149  msg = createPQExpBuffer();
5150 
5152  if (fld)
5153  printfPQExpBuffer(msg, "%s: ", fld);
5154  else
5155  printfPQExpBuffer(msg, "ERROR: ");
5157  if (fld)
5158  appendPQExpBufferStr(msg, fld);
5159  else
5160  appendPQExpBufferStr(msg, "(not available)");
5161  appendPQExpBufferChar(msg, '\n');
5162 
5163  pg_log_error("%s", msg->data);
5164 
5165  destroyPQExpBuffer(msg);
5166 }
static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1805
static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1155
char * gset_prefix
Definition: settings.h:96
static void usage(void)
Definition: pg_standby.c:589
static char password[100]
Definition: streamutil.c:53
static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1537
static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2505
static void ignore_boolean_expression(PsqlScanState scan_state)
Definition: command.c:2849
bool do_lo_export(const char *loid_arg, const char *filename_arg)
Definition: large_obj.c:142
static bool param_is_newly_set(const char *old_val, const char *new_val)
Definition: command.c:3001
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
void psql_scan_slash_command_end(PsqlScanState state)
EditableObjectType
Definition: command.c:49
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
static backslashResult exec_command_else(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1700
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:128
volatile bool sigint_interrupt_enabled
Definition: common.c:245
char * nullPrint
Definition: print.h:170
static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2027
static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch)
Definition: command.c:430
void print_copyright(void)
Definition: help.c:670
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
int encoding
Definition: print.h:122
#define EXIT_SUCCESS
Definition: settings.h:150
PsqlSettings pset
Definition: startup.c:31
PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
Definition: fe-connect.c:6848
void conditional_stack_set_query_len(ConditionalStack cstack, int len)
Definition: conditional.c:139
const printTextFormat * line_style
Definition: print.h:115
bool listOperatorClasses(const char *access_method_pattern, const char *type_pattern, bool verbose)
Definition: describe.c:6062
void SyncVariables(void)
Definition: command.c:3461
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
bool listTSConfigs(const char *pattern, bool verbose)
Definition: describe.c:5039
static void error(void)
Definition: sql-dyntest.c:147
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6637
bool objectDescription(const char *pattern, bool showSystem)
Definition: describe.c:1175
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
bool conditional_stack_pop(ConditionalStack cstack)
Definition: conditional.c:57
int PSQLexecWatch(const char *query, const printQueryOpt *opt)
Definition: common.c:591
static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1487
static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:2928
bool listExtensionContents(const char *pattern)
Definition: describe.c:5606
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void disable_sigpipe_trap(void)
Definition: print.c:2925
static void output(uint64 loop_count)
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
#define pg_log_error(...)
Definition: logging.h:79
static bool is_branching_command(const char *cmd)
Definition: command.c:2912
static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name)
Definition: command.c:2832
void ResetCancelConn(void)
Definition: cancel.c:100
printTextFormat pg_utf8format
Definition: print.c:99
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:956
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
char * psql_scan_slash_command(PsqlScanState state)
void ClosePager(FILE *pagerpipe)
Definition: print.c:3026
static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1268
const printTextFormat pg_asciiformat_old
Definition: print.c:77
bool do_lo_unlink(const char *loid_arg)
Definition: large_obj.c:239
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
bool recognized_connection_string(const char *connstr)
Definition: common.c:2303
void conditional_stack_push(ConditionalStack cstack, ifState new_state)
Definition: conditional.c:41
static void minimal_error_message(PGresult *res)
Definition: command.c:5144
bool gexec_flag
Definition: settings.h:98
void psql_scan_set_paren_depth(PsqlScanState state, int depth)
enum printFormat format
Definition: print.h:101
void PsqlVarEnumError(const char *name, const char *value, const char *suggestions)
Definition: variables.c:391
int conditional_stack_get_query_len(ConditionalStack cstack)
Definition: conditional.c:150
bool listOpFamilyOperators(const char *access_method_pattern, const char *family_pattern, bool verbose)
Definition: describe.c:6240
#define Min(x, y)
Definition: c.h:927
printTableOpt topt
Definition: print.h:169
unicode_linestyle
Definition: print.h:87
bool listEventTriggers(const char *pattern, bool verbose)
Definition: describe.c:4310
printQueryOpt * gsavepopt
Definition: settings.h:94
bool listCollations(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4494
bool listLanguages(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4073
static bool lookup_object_oid(EditableObjectType obj_type, const char *desc, Oid *obj_oid)
Definition: command.c:4785
static void print_with_linenumbers(FILE *output, char *lines, const char *header_keyword)
Definition: command.c:5103
static backslashResult exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2730
static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:1933
static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2429
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:545
FILE * queryFout
Definition: settings.h:84
void canonicalize_path(char *path)
Definition: path.c:254
printQueryOpt * savePsetInfo(const printQueryOpt *popt)
Definition: command.c:4420
static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2101
unicode_linestyle unicode_header_linestyle
Definition: print.h:127
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4170
char * PQport(const PGconn *conn)
Definition: fe-connect.c:6591
static const char * _unicode_linestyle2string(int linestyle)
Definition: command.c:3877
static backslashResult exec_command_errverbose(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1238
#define printf(...)
Definition: port.h:199
char * inputfile
Definition: settings.h:110
bool do_copy(const char *args)
Definition: copy.c:268
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define lengthof(array)
Definition: c.h:675
static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1959
static void printGSSInfo(void)
Definition: command.c:3420
NameData relname
Definition: pg_class.h:38
unsigned int Oid
Definition: postgres_ext.h:31
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6662
bool listDomains(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4148
const char * name
Definition: print.h:72
void PrintVariables(VariableSpace space)
Definition: variables.c:186
static char * read_connect_arg(PsqlScanState scan_state)
Definition: command.c:2762
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define fprintf
Definition: port.h:197
bool listSchemas(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4593
void conditional_stack_set_paren_depth(ConditionalStack cstack, int depth)
Definition: conditional.c:161
#define PG_BINARY_R
Definition: c.h:1213
bool separator_zero
Definition: print.h:96
static int fd(const char *x, int i)
Definition: preproc-init.c:105
unicode_linestyle unicode_border_linestyle
Definition: print.h:125
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6732
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
bool describeTablespaces(const char *pattern, bool verbose)
Definition: describe.c:219
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:646
void UnsyncVariables(void)
Definition: command.c:3502
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6530
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:247
static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2685
bool describeSubscriptions(const char *pattern, bool verbose)
Definition: describe.c:5960
static int count_lines_in_buf(PQExpBuffer buf)
Definition: command.c:5076
static backslashResult process_command_g_options(char *first_option, PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1349
static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1296
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define true
Definition: c.h:328
void pg_usleep(long microsec)
Definition: signal.c:53
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
unsigned short int border
Definition: print.h:104
char * ctv_args[4]
Definition: settings.h:100
bool has_drive_prefix(const char *filename)
Definition: path.c:87
static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:2624
bool describeAggregates(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:63
unsigned short int expanded
Definition: print.h:102
static backslashResult exec_command(const char *cmd, PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:277
bool cur_cmd_interactive
Definition: settings.h:107
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:135
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:2975
static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2708
PGconn * conn
Definition: streamutil.c:54
static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2267
void expand_tilde(char **filename)
Definition: common.c:2218
static const char * pset_bool_string(bool val)
Definition: command.c:4487
static bool do_watch(PQExpBuffer query_buf, double sleep)
Definition: command.c:4647
char * psql_scan_slash_option(PsqlScanState state, enum slash_option_type type, char *quote, bool semicolon)
#define MAXPGPATH
unicode_linestyle unicode_column_linestyle
Definition: print.h:126
bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:3668
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
Definition: command.c:4456
static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
Definition: command.c:593
bool describeTableDetails(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:1367
bool tuples_only
Definition: print.h:110
bool gdesc_flag
Definition: settings.h:97
bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
Definition: describe.c:3869
char * PQresultVerboseErrorMessage(const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
Definition: fe-exec.c:2716
char * c
static char * buf
Definition: pg_test_fsync.c:67
bool listConversions(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4234
static void ignore_slash_filepipe(PsqlScanState scan_state)
Definition: command.c:2882
void simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
Definition: sprompt.c:37
void psql_scan_reset(PsqlScanState state)
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, bool is_func)
Definition: command.c:1033
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:6504
#define is_absolute_path(filename)
Definition: port.h:86
static backslashResult exec_command_elif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1624
bool appendReloptionsArray(PQExpBuffer buffer, const char *reloptions, const char *prefix, int encoding, bool std_strings)
Definition: string_utils.c:741
void get_parent_directory(char *path)
Definition: path.c:854
#define PG_DIAG_SEVERITY
Definition: postgres_ext.h:55
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:6538
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:6463
bool do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
Definition: command.c:3907
char * tableAttr
Definition: print.h:121
static bool editFile(const char *fname, int lineno)
Definition: command.c:3521
static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch)
Definition: command.c:674
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
bool do_lo_import(const char *filename_arg, const char *comment_arg)
Definition: large_obj.c:176
#define atooid(x)
Definition: postgres_ext.h:42
static PQExpBuffer gather_boolean_expression(PsqlScanState scan_state)
Definition: command.c:2802
static char * prompt_for_password(const char *username)
Definition: command.c:2983
void restore_sigpipe_trap(void)
Definition: print.c:2948
static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch)
Definition: command.c:482
static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1458
bool listForeignTables(const char *pattern, bool verbose)
Definition: describe.c:5471
char * PQhostaddr(const PGconn *conn)
Definition: fe-connect.c:6578
static int port
Definition: pg_regress.c:90
char csvFieldSep[2]
Definition: print.h:118
#define DEFAULT_EDITOR
Definition: settings.h:22
static backslashResult exec_command_endif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1765
bool describePublications(const char *pattern)
Definition: describe.c:5794
static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2214
#define stat(a, b)
Definition: win32_port.h:255
trivalue
Definition: vacuumlo.c:33
#define PARAMS_ARRAY_SIZE
#define ngettext(s, p, n)
Definition: c.h:1123
static backslashResult exec_command_if(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1578
static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1441
PGContextVisibility show_context
Definition: settings.h:143
char * gfname
Definition: settings.h:93
void helpVariables(unsigned short int pager)
Definition: help.c:340
bool listTSDictionaries(const char *pattern, bool verbose)
Definition: describe.c:4897
static bool printPsetInfo(const char *param, printQueryOpt *popt)
Definition: command.c:4233
bool setQFout(const char *fname)
Definition: common.c:85
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2473
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:2948
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:6740
PGresult * last_error_result
Definition: settings.h:89
static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, int lineno, bool *edited)
Definition: command.c:3589
FILE * logfile
Definition: settings.h:116
PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
Definition: fe-connect.c:6798
bool listPublications(const char *pattern)
Definition: describe.c:5719
bool listForeignServers(const char *pattern, bool verbose)
Definition: describe.c:5328
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
ifState conditional_stack_peek(ConditionalStack cstack)
Definition: conditional.c:94
unsigned short int pager
Definition: print.h:106
static char * username
Definition: initdb.c:133
static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1200
#define InvalidOid
Definition: postgres_ext.h:36
static struct @143 value
PGVerbosity verbosity
Definition: settings.h:142
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:6555
int process_file(char *filename, bool use_relative_path)
Definition: command.c:3754
int psql_scan_get_paren_depth(PsqlScanState state)