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