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