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