PostgreSQL Source Code  git master
command.c
Go to the documentation of this file.
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2020, PostgreSQL Global Development Group
5  *
6  * src/bin/psql/command.c
7  */
8 #include "postgres_fe.h"
9 
10 #include <ctype.h>
11 #include <time.h>
12 #include <pwd.h>
13 #ifndef WIN32
14 #include <sys/stat.h> /* for stat() */
15 #include <fcntl.h> /* open() flags */
16 #include <unistd.h> /* for geteuid(), getpid(), stat() */
17 #else
18 #include <win32.h>
19 #include <io.h>
20 #include <fcntl.h>
21 #include <direct.h>
22 #include <sys/stat.h> /* for stat() */
23 #endif
24 
25 #include "catalog/pg_class_d.h"
26 #include "command.h"
27 #include "common.h"
28 #include "common/logging.h"
29 #include "copy.h"
30 #include "crosstabview.h"
31 #include "describe.h"
32 #include "fe_utils/cancel.h"
33 #include "fe_utils/print.h"
34 #include "fe_utils/string_utils.h"
35 #include "help.h"
36 #include "input.h"
37 #include "large_obj.h"
38 #include "libpq-fe.h"
39 #include "mainloop.h"
40 #include "portability/instr_time.h"
41 #include "pqexpbuffer.h"
42 #include "psqlscanslash.h"
43 #include "settings.h"
44 #include "variables.h"
45 
46 /*
47  * Editable database object types.
48  */
49 typedef enum EditableObjectType
50 {
54 
55 /* local function declarations */
56 static backslashResult exec_command(const char *cmd,
57  PsqlScanState scan_state,
58  ConditionalStack cstack,
59  PQExpBuffer query_buf,
60  PQExpBuffer previous_buf);
61 static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch);
62 static backslashResult exec_command_C(PsqlScanState scan_state, bool active_branch);
63 static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch);
64 static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch,
65  const char *cmd);
66 static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch);
67 static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch);
68 static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch);
69 static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch);
70 static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch,
71  const char *cmd);
72 static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
73  PQExpBuffer query_buf, PQExpBuffer previous_buf);
74 static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
75  PQExpBuffer query_buf, bool is_func);
76 static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch,
77  const char *cmd);
79  PQExpBuffer query_buf);
81  PQExpBuffer query_buf);
83  PQExpBuffer query_buf);
84 static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch);
85 static backslashResult exec_command_errverbose(PsqlScanState scan_state, bool active_branch);
86 static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch);
87 static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch,
88  const char *cmd);
89 static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch);
90 static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch);
91 static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch);
92 static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch);
93 static backslashResult exec_command_html(PsqlScanState scan_state, bool active_branch);
94 static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch,
95  const char *cmd);
97  PQExpBuffer query_buf);
98 static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch,
99  const char *cmd);
100 static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_branch,
101  const char *cmd);
102 static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch);
103 static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch,
104  PQExpBuffer query_buf, PQExpBuffer previous_buf);
105 static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch);
106 static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch,
107  const char *cmd);
108 static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch);
109 static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch);
110 static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch,
111  PQExpBuffer query_buf);
112 static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch);
113 static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch);
114 static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch,
115  const char *cmd);
116 static backslashResult exec_command_sf_sv(PsqlScanState scan_state, bool active_branch,
117  const char *cmd, bool is_func);
118 static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch);
119 static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch);
120 static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch);
121 static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch,
122  const char *cmd);
123 static backslashResult exec_command_write(PsqlScanState scan_state, bool active_branch,
124  const char *cmd,
125  PQExpBuffer query_buf, PQExpBuffer previous_buf);
126 static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch,
127  PQExpBuffer query_buf, PQExpBuffer previous_buf);
128 static backslashResult exec_command_x(PsqlScanState scan_state, bool active_branch);
129 static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch);
130 static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch);
131 static backslashResult exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch);
132 static char *read_connect_arg(PsqlScanState scan_state);
134 static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name);
135 static void ignore_boolean_expression(PsqlScanState scan_state);
136 static void ignore_slash_options(PsqlScanState scan_state);
137 static void ignore_slash_filepipe(PsqlScanState scan_state);
138 static void ignore_slash_whole_line(PsqlScanState scan_state);
139 static bool is_branching_command(const char *cmd);
140 static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack,
141  PQExpBuffer query_buf);
142 static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack,
143  PQExpBuffer query_buf);
144 static void copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf);
145 static bool do_connect(enum trivalue reuse_previous_specification,
146  char *dbname, char *user, char *host, char *port);
147 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
148  int lineno, bool *edited);
149 static bool do_shell(const char *command);
150 static bool do_watch(PQExpBuffer query_buf, double sleep);
151 static bool lookup_object_oid(EditableObjectType obj_type, const char *desc,
152  Oid *obj_oid);
153 static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid,
154  PQExpBuffer buf);
155 static int strip_lineno_from_objdesc(char *obj);
157 static void print_with_linenumbers(FILE *output, char *lines,
158  const char *header_keyword);
159 static void minimal_error_message(PGresult *res);
160 
161 static void printSSLInfo(void);
162 static void printGSSInfo(void);
163 static bool printPsetInfo(const char *param, struct printQueryOpt *popt);
164 static char *pset_value_string(const char *param, struct printQueryOpt *popt);
165 
166 #ifdef WIN32
167 static void checkWin32Codepage(void);
168 #endif
169 
170 
171 
172 /*----------
173  * HandleSlashCmds:
174  *
175  * Handles all the different commands that start with '\'.
176  * Ordinarily called by MainLoop().
177  *
178  * scan_state is a lexer working state that is set to continue scanning
179  * just after the '\'. The lexer is advanced past the command and all
180  * arguments on return.
181  *
182  * cstack is the current \if stack state. This will be examined, and
183  * possibly modified by conditional commands.
184  *
185  * query_buf contains the query-so-far, which may be modified by
186  * execution of the backslash command (for example, \r clears it).
187  *
188  * previous_buf contains the query most recently sent to the server
189  * (empty if none yet). This should not be modified here, but some
190  * commands copy its content into query_buf.
191  *
192  * query_buf and previous_buf will be NULL when executing a "-c"
193  * command-line option.
194  *
195  * Returns a status code indicating what action is desired, see command.h.
196  *----------
197  */
198 
201  ConditionalStack cstack,
202  PQExpBuffer query_buf,
203  PQExpBuffer previous_buf)
204 {
206  char *cmd;
207  char *arg;
208 
209  Assert(scan_state != NULL);
210  Assert(cstack != NULL);
211 
212  /* Parse off the command name */
213  cmd = psql_scan_slash_command(scan_state);
214 
215  /* And try to execute it */
216  status = exec_command(cmd, scan_state, cstack, query_buf, previous_buf);
217 
218  if (status == PSQL_CMD_UNKNOWN)
219  {
220  pg_log_error("invalid command \\%s", cmd);
222  pg_log_info("Try \\? for help.");
223  status = PSQL_CMD_ERROR;
224  }
225 
226  if (status != PSQL_CMD_ERROR)
227  {
228  /*
229  * Eat any remaining arguments after a valid command. We want to
230  * suppress evaluation of backticks in this situation, so transiently
231  * push an inactive conditional-stack entry.
232  */
233  bool active_branch = conditional_active(cstack);
234 
236  while ((arg = psql_scan_slash_option(scan_state,
237  OT_NORMAL, NULL, false)))
238  {
239  if (active_branch)
240  pg_log_warning("\\%s: extra argument \"%s\" ignored", cmd, arg);
241  free(arg);
242  }
243  conditional_stack_pop(cstack);
244  }
245  else
246  {
247  /* silently throw away rest of line after an erroneous command */
248  while ((arg = psql_scan_slash_option(scan_state,
249  OT_WHOLE_LINE, NULL, false)))
250  free(arg);
251  }
252 
253  /* if there is a trailing \\, swallow it */
254  psql_scan_slash_command_end(scan_state);
255 
256  free(cmd);
257 
258  /* some commands write to queryFout, so make sure output is sent */
259  fflush(pset.queryFout);
260 
261  return status;
262 }
263 
264 
265 /*
266  * Subroutine to actually try to execute a backslash command.
267  *
268  * The typical "success" result code is PSQL_CMD_SKIP_LINE, although some
269  * commands return something else. Failure results are PSQL_CMD_ERROR,
270  * unless PSQL_CMD_UNKNOWN is more appropriate.
271  */
272 static backslashResult
273 exec_command(const char *cmd,
274  PsqlScanState scan_state,
275  ConditionalStack cstack,
276  PQExpBuffer query_buf,
277  PQExpBuffer previous_buf)
278 {
280  bool active_branch = conditional_active(cstack);
281 
282  /*
283  * In interactive mode, warn when we're ignoring a command within a false
284  * \if-branch. But we continue on, so as to parse and discard the right
285  * amount of parameter text. Each individual backslash command subroutine
286  * is responsible for doing nothing after discarding appropriate
287  * arguments, if !active_branch.
288  */
289  if (pset.cur_cmd_interactive && !active_branch &&
290  !is_branching_command(cmd))
291  {
292  pg_log_warning("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block",
293  cmd);
294  }
295 
296  if (strcmp(cmd, "a") == 0)
297  status = exec_command_a(scan_state, active_branch);
298  else if (strcmp(cmd, "C") == 0)
299  status = exec_command_C(scan_state, active_branch);
300  else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
301  status = exec_command_connect(scan_state, active_branch);
302  else if (strcmp(cmd, "cd") == 0)
303  status = exec_command_cd(scan_state, active_branch, cmd);
304  else if (strcmp(cmd, "conninfo") == 0)
305  status = exec_command_conninfo(scan_state, active_branch);
306  else if (pg_strcasecmp(cmd, "copy") == 0)
307  status = exec_command_copy(scan_state, active_branch);
308  else if (strcmp(cmd, "copyright") == 0)
309  status = exec_command_copyright(scan_state, active_branch);
310  else if (strcmp(cmd, "crosstabview") == 0)
311  status = exec_command_crosstabview(scan_state, active_branch);
312  else if (cmd[0] == 'd')
313  status = exec_command_d(scan_state, active_branch, cmd);
314  else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
315  status = exec_command_edit(scan_state, active_branch,
316  query_buf, previous_buf);
317  else if (strcmp(cmd, "ef") == 0)
318  status = exec_command_ef_ev(scan_state, active_branch, query_buf, true);
319  else if (strcmp(cmd, "ev") == 0)
320  status = exec_command_ef_ev(scan_state, active_branch, query_buf, false);
321  else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0 ||
322  strcmp(cmd, "warn") == 0)
323  status = exec_command_echo(scan_state, active_branch, cmd);
324  else if (strcmp(cmd, "elif") == 0)
325  status = exec_command_elif(scan_state, cstack, query_buf);
326  else if (strcmp(cmd, "else") == 0)
327  status = exec_command_else(scan_state, cstack, query_buf);
328  else if (strcmp(cmd, "endif") == 0)
329  status = exec_command_endif(scan_state, cstack, query_buf);
330  else if (strcmp(cmd, "encoding") == 0)
331  status = exec_command_encoding(scan_state, active_branch);
332  else if (strcmp(cmd, "errverbose") == 0)
333  status = exec_command_errverbose(scan_state, active_branch);
334  else if (strcmp(cmd, "f") == 0)
335  status = exec_command_f(scan_state, active_branch);
336  else if (strcmp(cmd, "g") == 0 || strcmp(cmd, "gx") == 0)
337  status = exec_command_g(scan_state, active_branch, cmd);
338  else if (strcmp(cmd, "gdesc") == 0)
339  status = exec_command_gdesc(scan_state, active_branch);
340  else if (strcmp(cmd, "gexec") == 0)
341  status = exec_command_gexec(scan_state, active_branch);
342  else if (strcmp(cmd, "gset") == 0)
343  status = exec_command_gset(scan_state, active_branch);
344  else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
345  status = exec_command_help(scan_state, active_branch);
346  else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
347  status = exec_command_html(scan_state, active_branch);
348  else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0 ||
349  strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
350  status = exec_command_include(scan_state, active_branch, cmd);
351  else if (strcmp(cmd, "if") == 0)
352  status = exec_command_if(scan_state, cstack, query_buf);
353  else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
354  strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
355  status = exec_command_list(scan_state, active_branch, cmd);
356  else if (strncmp(cmd, "lo_", 3) == 0)
357  status = exec_command_lo(scan_state, active_branch, cmd);
358  else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
359  status = exec_command_out(scan_state, active_branch);
360  else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
361  status = exec_command_print(scan_state, active_branch,
362  query_buf, previous_buf);
363  else if (strcmp(cmd, "password") == 0)
364  status = exec_command_password(scan_state, active_branch);
365  else if (strcmp(cmd, "prompt") == 0)
366  status = exec_command_prompt(scan_state, active_branch, cmd);
367  else if (strcmp(cmd, "pset") == 0)
368  status = exec_command_pset(scan_state, active_branch);
369  else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
370  status = exec_command_quit(scan_state, active_branch);
371  else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
372  status = exec_command_reset(scan_state, active_branch, query_buf);
373  else if (strcmp(cmd, "s") == 0)
374  status = exec_command_s(scan_state, active_branch);
375  else if (strcmp(cmd, "set") == 0)
376  status = exec_command_set(scan_state, active_branch);
377  else if (strcmp(cmd, "setenv") == 0)
378  status = exec_command_setenv(scan_state, active_branch, cmd);
379  else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
380  status = exec_command_sf_sv(scan_state, active_branch, cmd, true);
381  else if (strcmp(cmd, "sv") == 0 || strcmp(cmd, "sv+") == 0)
382  status = exec_command_sf_sv(scan_state, active_branch, cmd, false);
383  else if (strcmp(cmd, "t") == 0)
384  status = exec_command_t(scan_state, active_branch);
385  else if (strcmp(cmd, "T") == 0)
386  status = exec_command_T(scan_state, active_branch);
387  else if (strcmp(cmd, "timing") == 0)
388  status = exec_command_timing(scan_state, active_branch);
389  else if (strcmp(cmd, "unset") == 0)
390  status = exec_command_unset(scan_state, active_branch, cmd);
391  else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
392  status = exec_command_write(scan_state, active_branch, cmd,
393  query_buf, previous_buf);
394  else if (strcmp(cmd, "watch") == 0)
395  status = exec_command_watch(scan_state, active_branch,
396  query_buf, previous_buf);
397  else if (strcmp(cmd, "x") == 0)
398  status = exec_command_x(scan_state, active_branch);
399  else if (strcmp(cmd, "z") == 0)
400  status = exec_command_z(scan_state, active_branch);
401  else if (strcmp(cmd, "!") == 0)
402  status = exec_command_shell_escape(scan_state, active_branch);
403  else if (strcmp(cmd, "?") == 0)
404  status = exec_command_slash_command_help(scan_state, active_branch);
405  else
406  status = PSQL_CMD_UNKNOWN;
407 
408  /*
409  * All the commands that return PSQL_CMD_SEND want to execute previous_buf
410  * if query_buf is empty. For convenience we implement that here, not in
411  * the individual command subroutines.
412  */
413  if (status == PSQL_CMD_SEND)
414  copy_previous_query(query_buf, previous_buf);
415 
416  return status;
417 }
418 
419 
420 /*
421  * \a -- toggle field alignment
422  *
423  * This makes little sense but we keep it around.
424  */
425 static backslashResult
426 exec_command_a(PsqlScanState scan_state, bool active_branch)
427 {
428  bool success = true;
429 
430  if (active_branch)
431  {
433  success = do_pset("format", "aligned", &pset.popt, pset.quiet);
434  else
435  success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
436  }
437 
438  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
439 }
440 
441 /*
442  * \C -- override table title (formerly change HTML caption)
443  */
444 static backslashResult
445 exec_command_C(PsqlScanState scan_state, bool active_branch)
446 {
447  bool success = true;
448 
449  if (active_branch)
450  {
451  char *opt = psql_scan_slash_option(scan_state,
452  OT_NORMAL, NULL, true);
453 
454  success = do_pset("title", opt, &pset.popt, pset.quiet);
455  free(opt);
456  }
457  else
458  ignore_slash_options(scan_state);
459 
460  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
461 }
462 
463 /*
464  * \c or \connect -- connect to database using the specified parameters.
465  *
466  * \c [-reuse-previous=BOOL] dbname user host port
467  *
468  * Specifying a parameter as '-' is equivalent to omitting it. Examples:
469  *
470  * \c - - hst Connect to current database on current port of
471  * host "hst" as current user.
472  * \c - usr - prt Connect to current database on port "prt" of current host
473  * as user "usr".
474  * \c dbs Connect to database "dbs" on current port of current host
475  * as current user.
476  */
477 static backslashResult
478 exec_command_connect(PsqlScanState scan_state, bool active_branch)
479 {
480  bool success = true;
481 
482  if (active_branch)
483  {
484  static const char prefix[] = "-reuse-previous=";
485  char *opt1,
486  *opt2,
487  *opt3,
488  *opt4;
489  enum trivalue reuse_previous = TRI_DEFAULT;
490 
491  opt1 = read_connect_arg(scan_state);
492  if (opt1 != NULL && strncmp(opt1, prefix, sizeof(prefix) - 1) == 0)
493  {
494  bool on_off;
495 
496  success = ParseVariableBool(opt1 + sizeof(prefix) - 1,
497  "-reuse-previous",
498  &on_off);
499  if (success)
500  {
501  reuse_previous = on_off ? TRI_YES : TRI_NO;
502  free(opt1);
503  opt1 = read_connect_arg(scan_state);
504  }
505  }
506 
507  if (success) /* give up if reuse_previous was invalid */
508  {
509  opt2 = read_connect_arg(scan_state);
510  opt3 = read_connect_arg(scan_state);
511  opt4 = read_connect_arg(scan_state);
512 
513  success = do_connect(reuse_previous, opt1, opt2, opt3, opt4);
514 
515  free(opt2);
516  free(opt3);
517  free(opt4);
518  }
519  free(opt1);
520  }
521  else
522  ignore_slash_options(scan_state);
523 
524  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
525 }
526 
527 /*
528  * \cd -- change directory
529  */
530 static backslashResult
531 exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
532 {
533  bool success = true;
534 
535  if (active_branch)
536  {
537  char *opt = psql_scan_slash_option(scan_state,
538  OT_NORMAL, NULL, true);
539  char *dir;
540 
541  if (opt)
542  dir = opt;
543  else
544  {
545 #ifndef WIN32
546  struct passwd *pw;
547  uid_t user_id = geteuid();
548 
549  errno = 0; /* clear errno before call */
550  pw = getpwuid(user_id);
551  if (!pw)
552  {
553  pg_log_error("could not get home directory for user ID %ld: %s",
554  (long) user_id,
555  errno ? strerror(errno) : _("user does not exist"));
556  exit(EXIT_FAILURE);
557  }
558  dir = pw->pw_dir;
559 #else /* WIN32 */
560 
561  /*
562  * On Windows, 'cd' without arguments prints the current
563  * directory, so if someone wants to code this here instead...
564  */
565  dir = "/";
566 #endif /* WIN32 */
567  }
568 
569  if (chdir(dir) == -1)
570  {
571  pg_log_error("\\%s: could not change directory to \"%s\": %m",
572  cmd, dir);
573  success = false;
574  }
575 
576  if (opt)
577  free(opt);
578  }
579  else
580  ignore_slash_options(scan_state);
581 
582  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
583 }
584 
585 /*
586  * \conninfo -- display information about the current connection
587  */
588 static backslashResult
589 exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
590 {
591  if (active_branch)
592  {
593  char *db = PQdb(pset.db);
594 
595  if (db == NULL)
596  printf(_("You are currently not connected to a database.\n"));
597  else
598  {
599  char *host = PQhost(pset.db);
600  char *hostaddr = PQhostaddr(pset.db);
601 
602  /*
603  * If the host is an absolute path, the connection is via socket
604  * unless overridden by hostaddr
605  */
606  if (is_absolute_path(host))
607  {
608  if (hostaddr && *hostaddr)
609  printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
610  db, PQuser(pset.db), hostaddr, PQport(pset.db));
611  else
612  printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
613  db, PQuser(pset.db), host, PQport(pset.db));
614  }
615  else
616  {
617  if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
618  printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
619  db, PQuser(pset.db), host, hostaddr, PQport(pset.db));
620  else
621  printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
622  db, PQuser(pset.db), host, PQport(pset.db));
623  }
624  printSSLInfo();
625  printGSSInfo();
626  }
627  }
628 
629  return PSQL_CMD_SKIP_LINE;
630 }
631 
632 /*
633  * \copy -- run a COPY command
634  */
635 static backslashResult
636 exec_command_copy(PsqlScanState scan_state, bool active_branch)
637 {
638  bool success = true;
639 
640  if (active_branch)
641  {
642  char *opt = psql_scan_slash_option(scan_state,
643  OT_WHOLE_LINE, NULL, false);
644 
645  success = do_copy(opt);
646  free(opt);
647  }
648  else
649  ignore_slash_whole_line(scan_state);
650 
651  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
652 }
653 
654 /*
655  * \copyright -- print copyright notice
656  */
657 static backslashResult
658 exec_command_copyright(PsqlScanState scan_state, bool active_branch)
659 {
660  if (active_branch)
661  print_copyright();
662 
663  return PSQL_CMD_SKIP_LINE;
664 }
665 
666 /*
667  * \crosstabview -- execute a query and display results in crosstab
668  */
669 static backslashResult
670 exec_command_crosstabview(PsqlScanState scan_state, bool active_branch)
671 {
673 
674  if (active_branch)
675  {
676  int i;
677 
678  for (i = 0; i < lengthof(pset.ctv_args); i++)
679  pset.ctv_args[i] = psql_scan_slash_option(scan_state,
680  OT_NORMAL, NULL, true);
681  pset.crosstab_flag = true;
682  status = PSQL_CMD_SEND;
683  }
684  else
685  ignore_slash_options(scan_state);
686 
687  return status;
688 }
689 
690 /*
691  * \d* commands
692  */
693 static backslashResult
694 exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
695 {
697  bool success = true;
698 
699  if (active_branch)
700  {
701  char *pattern;
702  bool show_verbose,
703  show_system;
704 
705  /* We don't do SQLID reduction on the pattern yet */
706  pattern = psql_scan_slash_option(scan_state,
707  OT_NORMAL, NULL, true);
708 
709  show_verbose = strchr(cmd, '+') ? true : false;
710  show_system = strchr(cmd, 'S') ? true : false;
711 
712  switch (cmd[1])
713  {
714  case '\0':
715  case '+':
716  case 'S':
717  if (pattern)
718  success = describeTableDetails(pattern, show_verbose, show_system);
719  else
720  /* standard listing of interesting things */
721  success = listTables("tvmsE", NULL, show_verbose, show_system);
722  break;
723  case 'A':
724  success = describeAccessMethods(pattern, show_verbose);
725  break;
726  case 'a':
727  success = describeAggregates(pattern, show_verbose, show_system);
728  break;
729  case 'b':
730  success = describeTablespaces(pattern, show_verbose);
731  break;
732  case 'c':
733  success = listConversions(pattern, show_verbose, show_system);
734  break;
735  case 'C':
736  success = listCasts(pattern, show_verbose);
737  break;
738  case 'd':
739  if (strncmp(cmd, "ddp", 3) == 0)
740  success = listDefaultACLs(pattern);
741  else
742  success = objectDescription(pattern, show_system);
743  break;
744  case 'D':
745  success = listDomains(pattern, show_verbose, show_system);
746  break;
747  case 'f': /* function subsystem */
748  switch (cmd[2])
749  {
750  case '\0':
751  case '+':
752  case 'S':
753  case 'a':
754  case 'n':
755  case 'p':
756  case 't':
757  case 'w':
758  success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
759  break;
760  default:
761  status = PSQL_CMD_UNKNOWN;
762  break;
763  }
764  break;
765  case 'g':
766  /* no longer distinct from \du */
767  success = describeRoles(pattern, show_verbose, show_system);
768  break;
769  case 'l':
770  success = do_lo_list();
771  break;
772  case 'L':
773  success = listLanguages(pattern, show_verbose, show_system);
774  break;
775  case 'n':
776  success = listSchemas(pattern, show_verbose, show_system);
777  break;
778  case 'o':
779  success = describeOperators(pattern, show_verbose, show_system);
780  break;
781  case 'O':
782  success = listCollations(pattern, show_verbose, show_system);
783  break;
784  case 'p':
785  success = permissionsList(pattern);
786  break;
787  case 'P':
788  {
789  switch (cmd[2])
790  {
791  case '\0':
792  case '+':
793  case 't':
794  case 'i':
795  case 'n':
796  success = listPartitionedTables(&cmd[2], pattern, show_verbose);
797  break;
798  default:
799  status = PSQL_CMD_UNKNOWN;
800  break;
801  }
802  }
803  break;
804  case 'T':
805  success = describeTypes(pattern, show_verbose, show_system);
806  break;
807  case 't':
808  case 'v':
809  case 'm':
810  case 'i':
811  case 's':
812  case 'E':
813  success = listTables(&cmd[1], pattern, show_verbose, show_system);
814  break;
815  case 'r':
816  if (cmd[2] == 'd' && cmd[3] == 's')
817  {
818  char *pattern2 = NULL;
819 
820  if (pattern)
821  pattern2 = psql_scan_slash_option(scan_state,
822  OT_NORMAL, NULL, true);
823  success = listDbRoleSettings(pattern, pattern2);
824 
825  if (pattern2)
826  free(pattern2);
827  }
828  else
829  status = PSQL_CMD_UNKNOWN;
830  break;
831  case 'R':
832  switch (cmd[2])
833  {
834  case 'p':
835  if (show_verbose)
836  success = describePublications(pattern);
837  else
838  success = listPublications(pattern);
839  break;
840  case 's':
841  success = describeSubscriptions(pattern, show_verbose);
842  break;
843  default:
844  status = PSQL_CMD_UNKNOWN;
845  }
846  break;
847  case 'u':
848  success = describeRoles(pattern, show_verbose, show_system);
849  break;
850  case 'F': /* text search subsystem */
851  switch (cmd[2])
852  {
853  case '\0':
854  case '+':
855  success = listTSConfigs(pattern, show_verbose);
856  break;
857  case 'p':
858  success = listTSParsers(pattern, show_verbose);
859  break;
860  case 'd':
861  success = listTSDictionaries(pattern, show_verbose);
862  break;
863  case 't':
864  success = listTSTemplates(pattern, show_verbose);
865  break;
866  default:
867  status = PSQL_CMD_UNKNOWN;
868  break;
869  }
870  break;
871  case 'e': /* SQL/MED subsystem */
872  switch (cmd[2])
873  {
874  case 's':
875  success = listForeignServers(pattern, show_verbose);
876  break;
877  case 'u':
878  success = listUserMappings(pattern, show_verbose);
879  break;
880  case 'w':
881  success = listForeignDataWrappers(pattern, show_verbose);
882  break;
883  case 't':
884  success = listForeignTables(pattern, show_verbose);
885  break;
886  default:
887  status = PSQL_CMD_UNKNOWN;
888  break;
889  }
890  break;
891  case 'x': /* Extensions */
892  if (show_verbose)
893  success = listExtensionContents(pattern);
894  else
895  success = listExtensions(pattern);
896  break;
897  case 'y': /* Event Triggers */
898  success = listEventTriggers(pattern, show_verbose);
899  break;
900  default:
901  status = PSQL_CMD_UNKNOWN;
902  }
903 
904  if (pattern)
905  free(pattern);
906  }
907  else
908  ignore_slash_options(scan_state);
909 
910  if (!success)
911  status = PSQL_CMD_ERROR;
912 
913  return status;
914 }
915 
916 /*
917  * \e or \edit -- edit the current query buffer, or edit a file and
918  * make it the query buffer
919  */
920 static backslashResult
921 exec_command_edit(PsqlScanState scan_state, bool active_branch,
922  PQExpBuffer query_buf, PQExpBuffer previous_buf)
923 {
925 
926  if (active_branch)
927  {
928  if (!query_buf)
929  {
930  pg_log_error("no query buffer");
931  status = PSQL_CMD_ERROR;
932  }
933  else
934  {
935  char *fname;
936  char *ln = NULL;
937  int lineno = -1;
938 
939  fname = psql_scan_slash_option(scan_state,
940  OT_NORMAL, NULL, true);
941  if (fname)
942  {
943  /* try to get separate lineno arg */
944  ln = psql_scan_slash_option(scan_state,
945  OT_NORMAL, NULL, true);
946  if (ln == NULL)
947  {
948  /* only one arg; maybe it is lineno not fname */
949  if (fname[0] &&
950  strspn(fname, "0123456789") == strlen(fname))
951  {
952  /* all digits, so assume it is lineno */
953  ln = fname;
954  fname = NULL;
955  }
956  }
957  }
958  if (ln)
959  {
960  lineno = atoi(ln);
961  if (lineno < 1)
962  {
963  pg_log_error("invalid line number: %s", ln);
964  status = PSQL_CMD_ERROR;
965  }
966  }
967  if (status != PSQL_CMD_ERROR)
968  {
969  expand_tilde(&fname);
970  if (fname)
971  canonicalize_path(fname);
972 
973  /* If query_buf is empty, recall previous query for editing */
974  copy_previous_query(query_buf, previous_buf);
975 
976  if (do_edit(fname, query_buf, lineno, NULL))
977  status = PSQL_CMD_NEWEDIT;
978  else
979  status = PSQL_CMD_ERROR;
980  }
981  if (fname)
982  free(fname);
983  if (ln)
984  free(ln);
985  }
986  }
987  else
988  ignore_slash_options(scan_state);
989 
990  return status;
991 }
992 
993 /*
994  * \ef/\ev -- edit the named function/view, or
995  * present a blank CREATE FUNCTION/VIEW template if no argument is given
996  */
997 static backslashResult
998 exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
999  PQExpBuffer query_buf, bool is_func)
1000 {
1002 
1003  if (active_branch)
1004  {
1005  char *obj_desc = psql_scan_slash_option(scan_state,
1006  OT_WHOLE_LINE,
1007  NULL, true);
1008  int lineno = -1;
1009 
1010  if (pset.sversion < (is_func ? 80400 : 70400))
1011  {
1012  char sverbuf[32];
1013 
1015  sverbuf, sizeof(sverbuf));
1016  if (is_func)
1017  pg_log_error("The server (version %s) does not support editing function source.",
1018  sverbuf);
1019  else
1020  pg_log_error("The server (version %s) does not support editing view definitions.",
1021  sverbuf);
1022  status = PSQL_CMD_ERROR;
1023  }
1024  else if (!query_buf)
1025  {
1026  pg_log_error("no query buffer");
1027  status = PSQL_CMD_ERROR;
1028  }
1029  else
1030  {
1031  Oid obj_oid = InvalidOid;
1033 
1034  lineno = strip_lineno_from_objdesc(obj_desc);
1035  if (lineno == 0)
1036  {
1037  /* error already reported */
1038  status = PSQL_CMD_ERROR;
1039  }
1040  else if (!obj_desc)
1041  {
1042  /* set up an empty command to fill in */
1043  resetPQExpBuffer(query_buf);
1044  if (is_func)
1045  appendPQExpBufferStr(query_buf,
1046  "CREATE FUNCTION ( )\n"
1047  " RETURNS \n"
1048  " LANGUAGE \n"
1049  " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
1050  "AS $function$\n"
1051  "\n$function$\n");
1052  else
1053  appendPQExpBufferStr(query_buf,
1054  "CREATE VIEW AS\n"
1055  " SELECT \n"
1056  " -- something...\n");
1057  }
1058  else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
1059  {
1060  /* error already reported */
1061  status = PSQL_CMD_ERROR;
1062  }
1063  else if (!get_create_object_cmd(eot, obj_oid, query_buf))
1064  {
1065  /* error already reported */
1066  status = PSQL_CMD_ERROR;
1067  }
1068  else if (is_func && lineno > 0)
1069  {
1070  /*
1071  * lineno "1" should correspond to the first line of the
1072  * function body. We expect that pg_get_functiondef() will
1073  * emit that on a line beginning with "AS ", and that there
1074  * can be no such line before the real start of the function
1075  * body. Increment lineno by the number of lines before that
1076  * line, so that it becomes relative to the first line of the
1077  * function definition.
1078  */
1079  const char *lines = query_buf->data;
1080 
1081  while (*lines != '\0')
1082  {
1083  if (strncmp(lines, "AS ", 3) == 0)
1084  break;
1085  lineno++;
1086  /* find start of next line */
1087  lines = strchr(lines, '\n');
1088  if (!lines)
1089  break;
1090  lines++;
1091  }
1092  }
1093  }
1094 
1095  if (status != PSQL_CMD_ERROR)
1096  {
1097  bool edited = false;
1098 
1099  if (!do_edit(NULL, query_buf, lineno, &edited))
1100  status = PSQL_CMD_ERROR;
1101  else if (!edited)
1102  puts(_("No changes"));
1103  else
1104  status = PSQL_CMD_NEWEDIT;
1105  }
1106 
1107  if (obj_desc)
1108  free(obj_desc);
1109  }
1110  else
1111  ignore_slash_whole_line(scan_state);
1112 
1113  return status;
1114 }
1115 
1116 /*
1117  * \echo, \qecho, and \warn -- echo arguments to stdout, query output, or stderr
1118  */
1119 static backslashResult
1120 exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
1121 {
1122  if (active_branch)
1123  {
1124  char *value;
1125  char quoted;
1126  bool no_newline = false;
1127  bool first = true;
1128  FILE *fout;
1129 
1130  if (strcmp(cmd, "qecho") == 0)
1131  fout = pset.queryFout;
1132  else if (strcmp(cmd, "warn") == 0)
1133  fout = stderr;
1134  else
1135  fout = stdout;
1136 
1137  while ((value = psql_scan_slash_option(scan_state,
1138  OT_NORMAL, &quoted, false)))
1139  {
1140  if (first && !no_newline && !quoted && strcmp(value, "-n") == 0)
1141  no_newline = true;
1142  else
1143  {
1144  if (first)
1145  first = false;
1146  else
1147  fputc(' ', fout);
1148  fputs(value, fout);
1149  }
1150  free(value);
1151  }
1152  if (!no_newline)
1153  fputs("\n", fout);
1154  }
1155  else
1156  ignore_slash_options(scan_state);
1157 
1158  return PSQL_CMD_SKIP_LINE;
1159 }
1160 
1161 /*
1162  * \encoding -- set/show client side encoding
1163  */
1164 static backslashResult
1165 exec_command_encoding(PsqlScanState scan_state, bool active_branch)
1166 {
1167  if (active_branch)
1168  {
1169  char *encoding = psql_scan_slash_option(scan_state,
1170  OT_NORMAL, NULL, false);
1171 
1172  if (!encoding)
1173  {
1174  /* show encoding */
1176  }
1177  else
1178  {
1179  /* set encoding */
1180  if (PQsetClientEncoding(pset.db, encoding) == -1)
1181  pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding);
1182  else
1183  {
1184  /* save encoding info into psql internal data */
1187  SetVariable(pset.vars, "ENCODING",
1189  }
1190  free(encoding);
1191  }
1192  }
1193  else
1194  ignore_slash_options(scan_state);
1195 
1196  return PSQL_CMD_SKIP_LINE;
1197 }
1198 
1199 /*
1200  * \errverbose -- display verbose message from last failed query
1201  */
1202 static backslashResult
1203 exec_command_errverbose(PsqlScanState scan_state, bool active_branch)
1204 {
1205  if (active_branch)
1206  {
1207  if (pset.last_error_result)
1208  {
1209  char *msg;
1210 
1214  if (msg)
1215  {
1216  pg_log_error("%s", msg);
1217  PQfreemem(msg);
1218  }
1219  else
1220  puts(_("out of memory"));
1221  }
1222  else
1223  puts(_("There is no previous error."));
1224  }
1225 
1226  return PSQL_CMD_SKIP_LINE;
1227 }
1228 
1229 /*
1230  * \f -- change field separator
1231  */
1232 static backslashResult
1233 exec_command_f(PsqlScanState scan_state, bool active_branch)
1234 {
1235  bool success = true;
1236 
1237  if (active_branch)
1238  {
1239  char *fname = psql_scan_slash_option(scan_state,
1240  OT_NORMAL, NULL, false);
1241 
1242  success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
1243  free(fname);
1244  }
1245  else
1246  ignore_slash_options(scan_state);
1247 
1248  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1249 }
1250 
1251 /*
1252  * \g [filename] -- send query, optionally with output to file/pipe
1253  * \gx [filename] -- same as \g, with expanded mode forced
1254  */
1255 static backslashResult
1256 exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
1257 {
1259 
1260  if (active_branch)
1261  {
1262  char *fname = psql_scan_slash_option(scan_state,
1263  OT_FILEPIPE, NULL, false);
1264 
1265  if (!fname)
1266  pset.gfname = NULL;
1267  else
1268  {
1269  expand_tilde(&fname);
1270  pset.gfname = pg_strdup(fname);
1271  }
1272  free(fname);
1273  if (strcmp(cmd, "gx") == 0)
1274  pset.g_expanded = true;
1275  status = PSQL_CMD_SEND;
1276  }
1277  else
1278  ignore_slash_filepipe(scan_state);
1279 
1280  return status;
1281 }
1282 
1283 /*
1284  * \gdesc -- describe query result
1285  */
1286 static backslashResult
1287 exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
1288 {
1290 
1291  if (active_branch)
1292  {
1293  pset.gdesc_flag = true;
1294  status = PSQL_CMD_SEND;
1295  }
1296 
1297  return status;
1298 }
1299 
1300 /*
1301  * \gexec -- send query and execute each field of result
1302  */
1303 static backslashResult
1304 exec_command_gexec(PsqlScanState scan_state, bool active_branch)
1305 {
1307 
1308  if (active_branch)
1309  {
1310  pset.gexec_flag = true;
1311  status = PSQL_CMD_SEND;
1312  }
1313 
1314  return status;
1315 }
1316 
1317 /*
1318  * \gset [prefix] -- send query and store result into variables
1319  */
1320 static backslashResult
1321 exec_command_gset(PsqlScanState scan_state, bool active_branch)
1322 {
1324 
1325  if (active_branch)
1326  {
1327  char *prefix = psql_scan_slash_option(scan_state,
1328  OT_NORMAL, NULL, false);
1329 
1330  if (prefix)
1331  pset.gset_prefix = prefix;
1332  else
1333  {
1334  /* we must set a non-NULL prefix to trigger storing */
1335  pset.gset_prefix = pg_strdup("");
1336  }
1337  /* gset_prefix is freed later */
1338  status = PSQL_CMD_SEND;
1339  }
1340  else
1341  ignore_slash_options(scan_state);
1342 
1343  return status;
1344 }
1345 
1346 /*
1347  * \help [topic] -- print help about SQL commands
1348  */
1349 static backslashResult
1350 exec_command_help(PsqlScanState scan_state, bool active_branch)
1351 {
1352  if (active_branch)
1353  {
1354  char *opt = psql_scan_slash_option(scan_state,
1355  OT_WHOLE_LINE, NULL, false);
1356  size_t len;
1357 
1358  /* strip any trailing spaces and semicolons */
1359  if (opt)
1360  {
1361  len = strlen(opt);
1362  while (len > 0 &&
1363  (isspace((unsigned char) opt[len - 1])
1364  || opt[len - 1] == ';'))
1365  opt[--len] = '\0';
1366  }
1367 
1368  helpSQL(opt, pset.popt.topt.pager);
1369  free(opt);
1370  }
1371  else
1372  ignore_slash_whole_line(scan_state);
1373 
1374  return PSQL_CMD_SKIP_LINE;
1375 }
1376 
1377 /*
1378  * \H and \html -- toggle HTML formatting
1379  */
1380 static backslashResult
1381 exec_command_html(PsqlScanState scan_state, bool active_branch)
1382 {
1383  bool success = true;
1384 
1385  if (active_branch)
1386  {
1387  if (pset.popt.topt.format != PRINT_HTML)
1388  success = do_pset("format", "html", &pset.popt, pset.quiet);
1389  else
1390  success = do_pset("format", "aligned", &pset.popt, pset.quiet);
1391  }
1392 
1393  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1394 }
1395 
1396 /*
1397  * \i and \ir -- include a file
1398  */
1399 static backslashResult
1400 exec_command_include(PsqlScanState scan_state, bool active_branch, const char *cmd)
1401 {
1402  bool success = true;
1403 
1404  if (active_branch)
1405  {
1406  char *fname = psql_scan_slash_option(scan_state,
1407  OT_NORMAL, NULL, true);
1408 
1409  if (!fname)
1410  {
1411  pg_log_error("\\%s: missing required argument", cmd);
1412  success = false;
1413  }
1414  else
1415  {
1416  bool include_relative;
1417 
1418  include_relative = (strcmp(cmd, "ir") == 0
1419  || strcmp(cmd, "include_relative") == 0);
1420  expand_tilde(&fname);
1421  success = (process_file(fname, include_relative) == EXIT_SUCCESS);
1422  free(fname);
1423  }
1424  }
1425  else
1426  ignore_slash_options(scan_state);
1427 
1428  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1429 }
1430 
1431 /*
1432  * \if <expr> -- beginning of an \if..\endif block
1433  *
1434  * <expr> is parsed as a boolean expression. Invalid expressions will emit a
1435  * warning and be treated as false. Statements that follow a false expression
1436  * will be parsed but ignored. Note that in the case where an \if statement
1437  * is itself within an inactive section of a block, then the entire inner
1438  * \if..\endif block will be parsed but ignored.
1439  */
1440 static backslashResult
1442  PQExpBuffer query_buf)
1443 {
1444  if (conditional_active(cstack))
1445  {
1446  /*
1447  * First, push a new active stack entry; this ensures that the lexer
1448  * will perform variable substitution and backtick evaluation while
1449  * scanning the expression. (That should happen anyway, since we know
1450  * we're in an active outer branch, but let's be sure.)
1451  */
1453 
1454  /* Remember current query state in case we need to restore later */
1455  save_query_text_state(scan_state, cstack, query_buf);
1456 
1457  /*
1458  * Evaluate the expression; if it's false, change to inactive state.
1459  */
1460  if (!is_true_boolean_expression(scan_state, "\\if expression"))
1462  }
1463  else
1464  {
1465  /*
1466  * We're within an inactive outer branch, so this entire \if block
1467  * will be ignored. We don't want to evaluate the expression, so push
1468  * the "ignored" stack state before scanning it.
1469  */
1471 
1472  /* Remember current query state in case we need to restore later */
1473  save_query_text_state(scan_state, cstack, query_buf);
1474 
1475  ignore_boolean_expression(scan_state);
1476  }
1477 
1478  return PSQL_CMD_SKIP_LINE;
1479 }
1480 
1481 /*
1482  * \elif <expr> -- alternative branch in an \if..\endif block
1483  *
1484  * <expr> is evaluated the same as in \if <expr>.
1485  */
1486 static backslashResult
1488  PQExpBuffer query_buf)
1489 {
1490  bool success = true;
1491 
1492  switch (conditional_stack_peek(cstack))
1493  {
1494  case IFSTATE_TRUE:
1495 
1496  /*
1497  * Just finished active branch of this \if block. Update saved
1498  * state so we will keep whatever data was put in query_buf by the
1499  * active branch.
1500  */
1501  save_query_text_state(scan_state, cstack, query_buf);
1502 
1503  /*
1504  * Discard \elif expression and ignore the rest until \endif.
1505  * Switch state before reading expression to ensure proper lexer
1506  * behavior.
1507  */
1509  ignore_boolean_expression(scan_state);
1510  break;
1511  case IFSTATE_FALSE:
1512 
1513  /*
1514  * Discard any query text added by the just-skipped branch.
1515  */
1516  discard_query_text(scan_state, cstack, query_buf);
1517 
1518  /*
1519  * Have not yet found a true expression in this \if block, so this
1520  * might be the first. We have to change state before examining
1521  * the expression, or the lexer won't do the right thing.
1522  */
1524  if (!is_true_boolean_expression(scan_state, "\\elif expression"))
1526  break;
1527  case IFSTATE_IGNORED:
1528 
1529  /*
1530  * Discard any query text added by the just-skipped branch.
1531  */
1532  discard_query_text(scan_state, cstack, query_buf);
1533 
1534  /*
1535  * Skip expression and move on. Either the \if block already had
1536  * an active section, or whole block is being skipped.
1537  */
1538  ignore_boolean_expression(scan_state);
1539  break;
1540  case IFSTATE_ELSE_TRUE:
1541  case IFSTATE_ELSE_FALSE:
1542  pg_log_error("\\elif: cannot occur after \\else");
1543  success = false;
1544  break;
1545  case IFSTATE_NONE:
1546  /* no \if to elif from */
1547  pg_log_error("\\elif: no matching \\if");
1548  success = false;
1549  break;
1550  }
1551 
1552  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1553 }
1554 
1555 /*
1556  * \else -- final alternative in an \if..\endif block
1557  *
1558  * Statements within an \else branch will only be executed if
1559  * all previous \if and \elif expressions evaluated to false
1560  * and the block was not itself being ignored.
1561  */
1562 static backslashResult
1564  PQExpBuffer query_buf)
1565 {
1566  bool success = true;
1567 
1568  switch (conditional_stack_peek(cstack))
1569  {
1570  case IFSTATE_TRUE:
1571 
1572  /*
1573  * Just finished active branch of this \if block. Update saved
1574  * state so we will keep whatever data was put in query_buf by the
1575  * active branch.
1576  */
1577  save_query_text_state(scan_state, cstack, query_buf);
1578 
1579  /* Now skip the \else branch */
1581  break;
1582  case IFSTATE_FALSE:
1583 
1584  /*
1585  * Discard any query text added by the just-skipped branch.
1586  */
1587  discard_query_text(scan_state, cstack, query_buf);
1588 
1589  /*
1590  * We've not found any true \if or \elif expression, so execute
1591  * the \else branch.
1592  */
1594  break;
1595  case IFSTATE_IGNORED:
1596 
1597  /*
1598  * Discard any query text added by the just-skipped branch.
1599  */
1600  discard_query_text(scan_state, cstack, query_buf);
1601 
1602  /*
1603  * Either we previously processed the active branch of this \if,
1604  * or the whole \if block is being skipped. Either way, skip the
1605  * \else branch.
1606  */
1608  break;
1609  case IFSTATE_ELSE_TRUE:
1610  case IFSTATE_ELSE_FALSE:
1611  pg_log_error("\\else: cannot occur after \\else");
1612  success = false;
1613  break;
1614  case IFSTATE_NONE:
1615  /* no \if to else from */
1616  pg_log_error("\\else: no matching \\if");
1617  success = false;
1618  break;
1619  }
1620 
1621  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1622 }
1623 
1624 /*
1625  * \endif -- ends an \if...\endif block
1626  */
1627 static backslashResult
1629  PQExpBuffer query_buf)
1630 {
1631  bool success = true;
1632 
1633  switch (conditional_stack_peek(cstack))
1634  {
1635  case IFSTATE_TRUE:
1636  case IFSTATE_ELSE_TRUE:
1637  /* Close the \if block, keeping the query text */
1638  success = conditional_stack_pop(cstack);
1639  Assert(success);
1640  break;
1641  case IFSTATE_FALSE:
1642  case IFSTATE_IGNORED:
1643  case IFSTATE_ELSE_FALSE:
1644 
1645  /*
1646  * Discard any query text added by the just-skipped branch.
1647  */
1648  discard_query_text(scan_state, cstack, query_buf);
1649 
1650  /* Close the \if block */
1651  success = conditional_stack_pop(cstack);
1652  Assert(success);
1653  break;
1654  case IFSTATE_NONE:
1655  /* no \if to end */
1656  pg_log_error("\\endif: no matching \\if");
1657  success = false;
1658  break;
1659  }
1660 
1661  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1662 }
1663 
1664 /*
1665  * \l -- list databases
1666  */
1667 static backslashResult
1668 exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
1669 {
1670  bool success = true;
1671 
1672  if (active_branch)
1673  {
1674  char *pattern;
1675  bool show_verbose;
1676 
1677  pattern = psql_scan_slash_option(scan_state,
1678  OT_NORMAL, NULL, true);
1679 
1680  show_verbose = strchr(cmd, '+') ? true : false;
1681 
1682  success = listAllDbs(pattern, show_verbose);
1683 
1684  if (pattern)
1685  free(pattern);
1686  }
1687  else
1688  ignore_slash_options(scan_state);
1689 
1690  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1691 }
1692 
1693 /*
1694  * \lo_* -- large object operations
1695  */
1696 static backslashResult
1697 exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
1698 {
1700  bool success = true;
1701 
1702  if (active_branch)
1703  {
1704  char *opt1,
1705  *opt2;
1706 
1707  opt1 = psql_scan_slash_option(scan_state,
1708  OT_NORMAL, NULL, true);
1709  opt2 = psql_scan_slash_option(scan_state,
1710  OT_NORMAL, NULL, true);
1711 
1712  if (strcmp(cmd + 3, "export") == 0)
1713  {
1714  if (!opt2)
1715  {
1716  pg_log_error("\\%s: missing required argument", cmd);
1717  success = false;
1718  }
1719  else
1720  {
1721  expand_tilde(&opt2);
1722  success = do_lo_export(opt1, opt2);
1723  }
1724  }
1725 
1726  else if (strcmp(cmd + 3, "import") == 0)
1727  {
1728  if (!opt1)
1729  {
1730  pg_log_error("\\%s: missing required argument", cmd);
1731  success = false;
1732  }
1733  else
1734  {
1735  expand_tilde(&opt1);
1736  success = do_lo_import(opt1, opt2);
1737  }
1738  }
1739 
1740  else if (strcmp(cmd + 3, "list") == 0)
1741  success = do_lo_list();
1742 
1743  else if (strcmp(cmd + 3, "unlink") == 0)
1744  {
1745  if (!opt1)
1746  {
1747  pg_log_error("\\%s: missing required argument", cmd);
1748  success = false;
1749  }
1750  else
1751  success = do_lo_unlink(opt1);
1752  }
1753 
1754  else
1755  status = PSQL_CMD_UNKNOWN;
1756 
1757  free(opt1);
1758  free(opt2);
1759  }
1760  else
1761  ignore_slash_options(scan_state);
1762 
1763  if (!success)
1764  status = PSQL_CMD_ERROR;
1765 
1766  return status;
1767 }
1768 
1769 /*
1770  * \o -- set query output
1771  */
1772 static backslashResult
1773 exec_command_out(PsqlScanState scan_state, bool active_branch)
1774 {
1775  bool success = true;
1776 
1777  if (active_branch)
1778  {
1779  char *fname = psql_scan_slash_option(scan_state,
1780  OT_FILEPIPE, NULL, true);
1781 
1782  expand_tilde(&fname);
1783  success = setQFout(fname);
1784  free(fname);
1785  }
1786  else
1787  ignore_slash_filepipe(scan_state);
1788 
1789  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1790 }
1791 
1792 /*
1793  * \p -- print the current query buffer
1794  */
1795 static backslashResult
1796 exec_command_print(PsqlScanState scan_state, bool active_branch,
1797  PQExpBuffer query_buf, PQExpBuffer previous_buf)
1798 {
1799  if (active_branch)
1800  {
1801  /*
1802  * We want to print the same thing \g would execute, but not to change
1803  * the query buffer state; so we can't use copy_previous_query().
1804  * Also, beware of possibility that buffer pointers are NULL.
1805  */
1806  if (query_buf && query_buf->len > 0)
1807  puts(query_buf->data);
1808  else if (previous_buf && previous_buf->len > 0)
1809  puts(previous_buf->data);
1810  else if (!pset.quiet)
1811  puts(_("Query buffer is empty."));
1812  fflush(stdout);
1813  }
1814 
1815  return PSQL_CMD_SKIP_LINE;
1816 }
1817 
1818 /*
1819  * \password -- set user password
1820  */
1821 static backslashResult
1822 exec_command_password(PsqlScanState scan_state, bool active_branch)
1823 {
1824  bool success = true;
1825 
1826  if (active_branch)
1827  {
1828  char *opt0 = psql_scan_slash_option(scan_state,
1829  OT_SQLID, NULL, true);
1830  char pw1[100];
1831  char pw2[100];
1832 
1833  simple_prompt("Enter new password: ", pw1, sizeof(pw1), false);
1834  simple_prompt("Enter it again: ", pw2, sizeof(pw2), false);
1835 
1836  if (strcmp(pw1, pw2) != 0)
1837  {
1838  pg_log_error("Passwords didn't match.");
1839  success = false;
1840  }
1841  else
1842  {
1843  char *user;
1844  char *encrypted_password;
1845 
1846  if (opt0)
1847  user = opt0;
1848  else
1849  user = PQuser(pset.db);
1850 
1851  encrypted_password = PQencryptPasswordConn(pset.db, pw1, user, NULL);
1852 
1853  if (!encrypted_password)
1854  {
1856  success = false;
1857  }
1858  else
1859  {
1861  PGresult *res;
1862 
1863  initPQExpBuffer(&buf);
1864  printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
1865  fmtId(user));
1866  appendStringLiteralConn(&buf, encrypted_password, pset.db);
1867  res = PSQLexec(buf.data);
1868  termPQExpBuffer(&buf);
1869  if (!res)
1870  success = false;
1871  else
1872  PQclear(res);
1873  PQfreemem(encrypted_password);
1874  }
1875  }
1876 
1877  if (opt0)
1878  free(opt0);
1879  }
1880  else
1881  ignore_slash_options(scan_state);
1882 
1883  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1884 }
1885 
1886 /*
1887  * \prompt -- prompt and set variable
1888  */
1889 static backslashResult
1890 exec_command_prompt(PsqlScanState scan_state, bool active_branch,
1891  const char *cmd)
1892 {
1893  bool success = true;
1894 
1895  if (active_branch)
1896  {
1897  char *opt,
1898  *prompt_text = NULL;
1899  char *arg1,
1900  *arg2;
1901 
1902  arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
1903  arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
1904 
1905  if (!arg1)
1906  {
1907  pg_log_error("\\%s: missing required argument", cmd);
1908  success = false;
1909  }
1910  else
1911  {
1912  char *result;
1913 
1914  if (arg2)
1915  {
1916  prompt_text = arg1;
1917  opt = arg2;
1918  }
1919  else
1920  opt = arg1;
1921 
1922  if (!pset.inputfile)
1923  {
1924  result = (char *) pg_malloc(4096);
1925  simple_prompt(prompt_text, result, 4096, true);
1926  }
1927  else
1928  {
1929  if (prompt_text)
1930  {
1931  fputs(prompt_text, stdout);
1932  fflush(stdout);
1933  }
1934  result = gets_fromFile(stdin);
1935  if (!result)
1936  {
1937  pg_log_error("\\%s: could not read value for variable",
1938  cmd);
1939  success = false;
1940  }
1941  }
1942 
1943  if (result &&
1944  !SetVariable(pset.vars, opt, result))
1945  success = false;
1946 
1947  if (result)
1948  free(result);
1949  if (prompt_text)
1950  free(prompt_text);
1951  free(opt);
1952  }
1953  }
1954  else
1955  ignore_slash_options(scan_state);
1956 
1957  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1958 }
1959 
1960 /*
1961  * \pset -- set printing parameters
1962  */
1963 static backslashResult
1964 exec_command_pset(PsqlScanState scan_state, bool active_branch)
1965 {
1966  bool success = true;
1967 
1968  if (active_branch)
1969  {
1970  char *opt0 = psql_scan_slash_option(scan_state,
1971  OT_NORMAL, NULL, false);
1972  char *opt1 = psql_scan_slash_option(scan_state,
1973  OT_NORMAL, NULL, false);
1974 
1975  if (!opt0)
1976  {
1977  /* list all variables */
1978 
1979  int i;
1980  static const char *const my_list[] = {
1981  "border", "columns", "csv_fieldsep", "expanded", "fieldsep",
1982  "fieldsep_zero", "footer", "format", "linestyle", "null",
1983  "numericlocale", "pager", "pager_min_lines",
1984  "recordsep", "recordsep_zero",
1985  "tableattr", "title", "tuples_only",
1986  "unicode_border_linestyle",
1987  "unicode_column_linestyle",
1988  "unicode_header_linestyle",
1989  NULL
1990  };
1991 
1992  for (i = 0; my_list[i] != NULL; i++)
1993  {
1994  char *val = pset_value_string(my_list[i], &pset.popt);
1995 
1996  printf("%-24s %s\n", my_list[i], val);
1997  free(val);
1998  }
1999 
2000  success = true;
2001  }
2002  else
2003  success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
2004 
2005  free(opt0);
2006  free(opt1);
2007  }
2008  else
2009  ignore_slash_options(scan_state);
2010 
2011  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2012 }
2013 
2014 /*
2015  * \q or \quit -- exit psql
2016  */
2017 static backslashResult
2018 exec_command_quit(PsqlScanState scan_state, bool active_branch)
2019 {
2021 
2022  if (active_branch)
2023  status = PSQL_CMD_TERMINATE;
2024 
2025  return status;
2026 }
2027 
2028 /*
2029  * \r -- reset (clear) the query buffer
2030  */
2031 static backslashResult
2032 exec_command_reset(PsqlScanState scan_state, bool active_branch,
2033  PQExpBuffer query_buf)
2034 {
2035  if (active_branch)
2036  {
2037  resetPQExpBuffer(query_buf);
2038  psql_scan_reset(scan_state);
2039  if (!pset.quiet)
2040  puts(_("Query buffer reset (cleared)."));
2041  }
2042 
2043  return PSQL_CMD_SKIP_LINE;
2044 }
2045 
2046 /*
2047  * \s -- save history in a file or show it on the screen
2048  */
2049 static backslashResult
2050 exec_command_s(PsqlScanState scan_state, bool active_branch)
2051 {
2052  bool success = true;
2053 
2054  if (active_branch)
2055  {
2056  char *fname = psql_scan_slash_option(scan_state,
2057  OT_NORMAL, NULL, true);
2058 
2059  expand_tilde(&fname);
2060  success = printHistory(fname, pset.popt.topt.pager);
2061  if (success && !pset.quiet && fname)
2062  printf(_("Wrote history to file \"%s\".\n"), fname);
2063  if (!fname)
2064  putchar('\n');
2065  free(fname);
2066  }
2067  else
2068  ignore_slash_options(scan_state);
2069 
2070  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2071 }
2072 
2073 /*
2074  * \set -- set variable
2075  */
2076 static backslashResult
2077 exec_command_set(PsqlScanState scan_state, bool active_branch)
2078 {
2079  bool success = true;
2080 
2081  if (active_branch)
2082  {
2083  char *opt0 = psql_scan_slash_option(scan_state,
2084  OT_NORMAL, NULL, false);
2085 
2086  if (!opt0)
2087  {
2088  /* list all variables */
2090  success = true;
2091  }
2092  else
2093  {
2094  /*
2095  * Set variable to the concatenation of the arguments.
2096  */
2097  char *newval;
2098  char *opt;
2099 
2100  opt = psql_scan_slash_option(scan_state,
2101  OT_NORMAL, NULL, false);
2102  newval = pg_strdup(opt ? opt : "");
2103  free(opt);
2104 
2105  while ((opt = psql_scan_slash_option(scan_state,
2106  OT_NORMAL, NULL, false)))
2107  {
2108  newval = pg_realloc(newval, strlen(newval) + strlen(opt) + 1);
2109  strcat(newval, opt);
2110  free(opt);
2111  }
2112 
2113  if (!SetVariable(pset.vars, opt0, newval))
2114  success = false;
2115 
2116  free(newval);
2117  }
2118  free(opt0);
2119  }
2120  else
2121  ignore_slash_options(scan_state);
2122 
2123  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2124 }
2125 
2126 /*
2127  * \setenv -- set environment variable
2128  */
2129 static backslashResult
2130 exec_command_setenv(PsqlScanState scan_state, bool active_branch,
2131  const char *cmd)
2132 {
2133  bool success = true;
2134 
2135  if (active_branch)
2136  {
2137  char *envvar = psql_scan_slash_option(scan_state,
2138  OT_NORMAL, NULL, false);
2139  char *envval = psql_scan_slash_option(scan_state,
2140  OT_NORMAL, NULL, false);
2141 
2142  if (!envvar)
2143  {
2144  pg_log_error("\\%s: missing required argument", cmd);
2145  success = false;
2146  }
2147  else if (strchr(envvar, '=') != NULL)
2148  {
2149  pg_log_error("\\%s: environment variable name must not contain \"=\"",
2150  cmd);
2151  success = false;
2152  }
2153  else if (!envval)
2154  {
2155  /* No argument - unset the environment variable */
2156  unsetenv(envvar);
2157  success = true;
2158  }
2159  else
2160  {
2161  /* Set variable to the value of the next argument */
2162  char *newval;
2163 
2164  newval = psprintf("%s=%s", envvar, envval);
2165  putenv(newval);
2166  success = true;
2167 
2168  /*
2169  * Do not free newval here, it will screw up the environment if
2170  * you do. See putenv man page for details. That means we leak a
2171  * bit of memory here, but not enough to worry about.
2172  */
2173  }
2174  free(envvar);
2175  free(envval);
2176  }
2177  else
2178  ignore_slash_options(scan_state);
2179 
2180  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2181 }
2182 
2183 /*
2184  * \sf/\sv -- show a function/view's source code
2185  */
2186 static backslashResult
2187 exec_command_sf_sv(PsqlScanState scan_state, bool active_branch,
2188  const char *cmd, bool is_func)
2189 {
2191 
2192  if (active_branch)
2193  {
2194  bool show_linenumbers = (strchr(cmd, '+') != NULL);
2195  PQExpBuffer buf;
2196  char *obj_desc;
2197  Oid obj_oid = InvalidOid;
2199 
2200  buf = createPQExpBuffer();
2201  obj_desc = psql_scan_slash_option(scan_state,
2202  OT_WHOLE_LINE, NULL, true);
2203  if (pset.sversion < (is_func ? 80400 : 70400))
2204  {
2205  char sverbuf[32];
2206 
2208  sverbuf, sizeof(sverbuf));
2209  if (is_func)
2210  pg_log_error("The server (version %s) does not support showing function source.",
2211  sverbuf);
2212  else
2213  pg_log_error("The server (version %s) does not support showing view definitions.",
2214  sverbuf);
2215  status = PSQL_CMD_ERROR;
2216  }
2217  else if (!obj_desc)
2218  {
2219  if (is_func)
2220  pg_log_error("function name is required");
2221  else
2222  pg_log_error("view name is required");
2223  status = PSQL_CMD_ERROR;
2224  }
2225  else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
2226  {
2227  /* error already reported */
2228  status = PSQL_CMD_ERROR;
2229  }
2230  else if (!get_create_object_cmd(eot, obj_oid, buf))
2231  {
2232  /* error already reported */
2233  status = PSQL_CMD_ERROR;
2234  }
2235  else
2236  {
2237  FILE *output;
2238  bool is_pager;
2239 
2240  /* Select output stream: stdout, pager, or file */
2241  if (pset.queryFout == stdout)
2242  {
2243  /* count lines in function to see if pager is needed */
2244  int lineno = count_lines_in_buf(buf);
2245 
2246  output = PageOutput(lineno, &(pset.popt.topt));
2247  is_pager = true;
2248  }
2249  else
2250  {
2251  /* use previously set output file, without pager */
2252  output = pset.queryFout;
2253  is_pager = false;
2254  }
2255 
2256  if (show_linenumbers)
2257  {
2258  /*
2259  * For functions, lineno "1" should correspond to the first
2260  * line of the function body. We expect that
2261  * pg_get_functiondef() will emit that on a line beginning
2262  * with "AS ", and that there can be no such line before the
2263  * real start of the function body.
2264  */
2265  print_with_linenumbers(output, buf->data,
2266  is_func ? "AS " : NULL);
2267  }
2268  else
2269  {
2270  /* just send the definition to output */
2271  fputs(buf->data, output);
2272  }
2273 
2274  if (is_pager)
2275  ClosePager(output);
2276  }
2277 
2278  if (obj_desc)
2279  free(obj_desc);
2280  destroyPQExpBuffer(buf);
2281  }
2282  else
2283  ignore_slash_whole_line(scan_state);
2284 
2285  return status;
2286 }
2287 
2288 /*
2289  * \t -- turn off table headers and row count
2290  */
2291 static backslashResult
2292 exec_command_t(PsqlScanState scan_state, bool active_branch)
2293 {
2294  bool success = true;
2295 
2296  if (active_branch)
2297  {
2298  char *opt = psql_scan_slash_option(scan_state,
2299  OT_NORMAL, NULL, true);
2300 
2301  success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
2302  free(opt);
2303  }
2304  else
2305  ignore_slash_options(scan_state);
2306 
2307  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2308 }
2309 
2310 /*
2311  * \T -- define html <table ...> attributes
2312  */
2313 static backslashResult
2314 exec_command_T(PsqlScanState scan_state, bool active_branch)
2315 {
2316  bool success = true;
2317 
2318  if (active_branch)
2319  {
2320  char *value = psql_scan_slash_option(scan_state,
2321  OT_NORMAL, NULL, false);
2322 
2323  success = do_pset("tableattr", value, &pset.popt, pset.quiet);
2324  free(value);
2325  }
2326  else
2327  ignore_slash_options(scan_state);
2328 
2329  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2330 }
2331 
2332 /*
2333  * \timing -- enable/disable timing of queries
2334  */
2335 static backslashResult
2336 exec_command_timing(PsqlScanState scan_state, bool active_branch)
2337 {
2338  bool success = true;
2339 
2340  if (active_branch)
2341  {
2342  char *opt = psql_scan_slash_option(scan_state,
2343  OT_NORMAL, NULL, false);
2344 
2345  if (opt)
2346  success = ParseVariableBool(opt, "\\timing", &pset.timing);
2347  else
2348  pset.timing = !pset.timing;
2349  if (!pset.quiet)
2350  {
2351  if (pset.timing)
2352  puts(_("Timing is on."));
2353  else
2354  puts(_("Timing is off."));
2355  }
2356  free(opt);
2357  }
2358  else
2359  ignore_slash_options(scan_state);
2360 
2361  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2362 }
2363 
2364 /*
2365  * \unset -- unset variable
2366  */
2367 static backslashResult
2368 exec_command_unset(PsqlScanState scan_state, bool active_branch,
2369  const char *cmd)
2370 {
2371  bool success = true;
2372 
2373  if (active_branch)
2374  {
2375  char *opt = psql_scan_slash_option(scan_state,
2376  OT_NORMAL, NULL, false);
2377 
2378  if (!opt)
2379  {
2380  pg_log_error("\\%s: missing required argument", cmd);
2381  success = false;
2382  }
2383  else if (!SetVariable(pset.vars, opt, NULL))
2384  success = false;
2385 
2386  free(opt);
2387  }
2388  else
2389  ignore_slash_options(scan_state);
2390 
2391  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2392 }
2393 
2394 /*
2395  * \w -- write query buffer to file
2396  */
2397 static backslashResult
2398 exec_command_write(PsqlScanState scan_state, bool active_branch,
2399  const char *cmd,
2400  PQExpBuffer query_buf, PQExpBuffer previous_buf)
2401 {
2403 
2404  if (active_branch)
2405  {
2406  char *fname = psql_scan_slash_option(scan_state,
2407  OT_FILEPIPE, NULL, true);
2408  FILE *fd = NULL;
2409  bool is_pipe = false;
2410 
2411  if (!query_buf)
2412  {
2413  pg_log_error("no query buffer");
2414  status = PSQL_CMD_ERROR;
2415  }
2416  else
2417  {
2418  if (!fname)
2419  {
2420  pg_log_error("\\%s: missing required argument", cmd);
2421  status = PSQL_CMD_ERROR;
2422  }
2423  else
2424  {
2425  expand_tilde(&fname);
2426  if (fname[0] == '|')
2427  {
2428  is_pipe = true;
2430  fd = popen(&fname[1], "w");
2431  }
2432  else
2433  {
2434  canonicalize_path(fname);
2435  fd = fopen(fname, "w");
2436  }
2437  if (!fd)
2438  {
2439  pg_log_error("%s: %m", fname);
2440  status = PSQL_CMD_ERROR;
2441  }
2442  }
2443  }
2444 
2445  if (fd)
2446  {
2447  int result;
2448 
2449  /*
2450  * We want to print the same thing \g would execute, but not to
2451  * change the query buffer state; so we can't use
2452  * copy_previous_query(). Also, beware of possibility that buffer
2453  * pointers are NULL.
2454  */
2455  if (query_buf && query_buf->len > 0)
2456  fprintf(fd, "%s\n", query_buf->data);
2457  else if (previous_buf && previous_buf->len > 0)
2458  fprintf(fd, "%s\n", previous_buf->data);
2459 
2460  if (is_pipe)
2461  result = pclose(fd);
2462  else
2463  result = fclose(fd);
2464 
2465  if (result == EOF)
2466  {
2467  pg_log_error("%s: %m", fname);
2468  status = PSQL_CMD_ERROR;
2469  }
2470  }
2471 
2472  if (is_pipe)
2474 
2475  free(fname);
2476  }
2477  else
2478  ignore_slash_filepipe(scan_state);
2479 
2480  return status;
2481 }
2482 
2483 /*
2484  * \watch -- execute a query every N seconds
2485  */
2486 static backslashResult
2487 exec_command_watch(PsqlScanState scan_state, bool active_branch,
2488  PQExpBuffer query_buf, PQExpBuffer previous_buf)
2489 {
2490  bool success = true;
2491 
2492  if (active_branch)
2493  {
2494  char *opt = psql_scan_slash_option(scan_state,
2495  OT_NORMAL, NULL, true);
2496  double sleep = 2;
2497 
2498  /* Convert optional sleep-length argument */
2499  if (opt)
2500  {
2501  sleep = strtod(opt, NULL);
2502  if (sleep <= 0)
2503  sleep = 1;
2504  free(opt);
2505  }
2506 
2507  /* If query_buf is empty, recall and execute previous query */
2508  copy_previous_query(query_buf, previous_buf);
2509 
2510  success = do_watch(query_buf, sleep);
2511 
2512  /* Reset the query buffer as though for \r */
2513  resetPQExpBuffer(query_buf);
2514  psql_scan_reset(scan_state);
2515  }
2516  else
2517  ignore_slash_options(scan_state);
2518 
2519  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2520 }
2521 
2522 /*
2523  * \x -- set or toggle expanded table representation
2524  */
2525 static backslashResult
2526 exec_command_x(PsqlScanState scan_state, bool active_branch)
2527 {
2528  bool success = true;
2529 
2530  if (active_branch)
2531  {
2532  char *opt = psql_scan_slash_option(scan_state,
2533  OT_NORMAL, NULL, true);
2534 
2535  success = do_pset("expanded", opt, &pset.popt, pset.quiet);
2536  free(opt);
2537  }
2538  else
2539  ignore_slash_options(scan_state);
2540 
2541  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2542 }
2543 
2544 /*
2545  * \z -- list table privileges (equivalent to \dp)
2546  */
2547 static backslashResult
2548 exec_command_z(PsqlScanState scan_state, bool active_branch)
2549 {
2550  bool success = true;
2551 
2552  if (active_branch)
2553  {
2554  char *pattern = psql_scan_slash_option(scan_state,
2555  OT_NORMAL, NULL, true);
2556 
2557  success = permissionsList(pattern);
2558  if (pattern)
2559  free(pattern);
2560  }
2561  else
2562  ignore_slash_options(scan_state);
2563 
2564  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2565 }
2566 
2567 /*
2568  * \! -- execute shell command
2569  */
2570 static backslashResult
2571 exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
2572 {
2573  bool success = true;
2574 
2575  if (active_branch)
2576  {
2577  char *opt = psql_scan_slash_option(scan_state,
2578  OT_WHOLE_LINE, NULL, false);
2579 
2580  success = do_shell(opt);
2581  free(opt);
2582  }
2583  else
2584  ignore_slash_whole_line(scan_state);
2585 
2586  return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
2587 }
2588 
2589 /*
2590  * \? -- print help about backslash commands
2591  */
2592 static backslashResult
2593 exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch)
2594 {
2595  if (active_branch)
2596  {
2597  char *opt0 = psql_scan_slash_option(scan_state,
2598  OT_NORMAL, NULL, false);
2599 
2600  if (!opt0 || strcmp(opt0, "commands") == 0)
2602  else if (strcmp(opt0, "options") == 0)
2604  else if (strcmp(opt0, "variables") == 0)
2606  else
2608 
2609  if (opt0)
2610  free(opt0);
2611  }
2612  else
2613  ignore_slash_options(scan_state);
2614 
2615  return PSQL_CMD_SKIP_LINE;
2616 }
2617 
2618 
2619 /*
2620  * Read and interpret an argument to the \connect slash command.
2621  *
2622  * Returns a malloc'd string, or NULL if no/empty argument.
2623  */
2624 static char *
2626 {
2627  char *result;
2628  char quote;
2629 
2630  /*
2631  * Ideally we should treat the arguments as SQL identifiers. But for
2632  * backwards compatibility with 7.2 and older pg_dump files, we have to
2633  * take unquoted arguments verbatim (don't downcase them). For now,
2634  * double-quoted arguments may be stripped of double quotes (as if SQL
2635  * identifiers). By 7.4 or so, pg_dump files can be expected to
2636  * double-quote all mixed-case \connect arguments, and then we can get rid
2637  * of OT_SQLIDHACK.
2638  */
2639  result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, &quote, true);
2640 
2641  if (!result)
2642  return NULL;
2643 
2644  if (quote)
2645  return result;
2646 
2647  if (*result == '\0' || strcmp(result, "-") == 0)
2648  {
2649  free(result);
2650  return NULL;
2651  }
2652 
2653  return result;
2654 }
2655 
2656 /*
2657  * Read a boolean expression, return it as a PQExpBuffer string.
2658  *
2659  * Note: anything more or less than one token will certainly fail to be
2660  * parsed by ParseVariableBool, so we don't worry about complaining here.
2661  * This routine's return data structure will need to be rethought anyway
2662  * to support likely future extensions such as "\if defined VARNAME".
2663  */
2664 static PQExpBuffer
2666 {
2667  PQExpBuffer exp_buf = createPQExpBuffer();
2668  int num_options = 0;
2669  char *value;
2670 
2671  /* collect all arguments for the conditional command into exp_buf */
2672  while ((value = psql_scan_slash_option(scan_state,
2673  OT_NORMAL, NULL, false)) != NULL)
2674  {
2675  /* add spaces between tokens */
2676  if (num_options > 0)
2677  appendPQExpBufferChar(exp_buf, ' ');
2678  appendPQExpBufferStr(exp_buf, value);
2679  num_options++;
2680  free(value);
2681  }
2682 
2683  return exp_buf;
2684 }
2685 
2686 /*
2687  * Read a boolean expression, return true if the expression
2688  * was a valid boolean expression that evaluated to true.
2689  * Otherwise return false.
2690  *
2691  * Note: conditional stack's top state must be active, else lexer will
2692  * fail to expand variables and backticks.
2693  */
2694 static bool
2696 {
2698  bool value = false;
2699  bool success = ParseVariableBool(buf->data, name, &value);
2700 
2701  destroyPQExpBuffer(buf);
2702  return success && value;
2703 }
2704 
2705 /*
2706  * Read a boolean expression, but do nothing with it.
2707  *
2708  * Note: conditional stack's top state must be INACTIVE, else lexer will
2709  * expand variables and backticks, which we do not want here.
2710  */
2711 static void
2713 {
2715 
2716  destroyPQExpBuffer(buf);
2717 }
2718 
2719 /*
2720  * Read and discard "normal" slash command options.
2721  *
2722  * This should be used for inactive-branch processing of any slash command
2723  * that eats one or more OT_NORMAL, OT_SQLID, or OT_SQLIDHACK parameters.
2724  * We don't need to worry about exactly how many it would eat, since the
2725  * cleanup logic in HandleSlashCmds would silently discard any extras anyway.
2726  */
2727 static void
2729 {
2730  char *arg;
2731 
2732  while ((arg = psql_scan_slash_option(scan_state,
2733  OT_NORMAL, NULL, false)) != NULL)
2734  free(arg);
2735 }
2736 
2737 /*
2738  * Read and discard FILEPIPE slash command argument.
2739  *
2740  * This *MUST* be used for inactive-branch processing of any slash command
2741  * that takes an OT_FILEPIPE option. Otherwise we might consume a different
2742  * amount of option text in active and inactive cases.
2743  */
2744 static void
2746 {
2747  char *arg = psql_scan_slash_option(scan_state,
2748  OT_FILEPIPE, NULL, false);
2749 
2750  if (arg)
2751  free(arg);
2752 }
2753 
2754 /*
2755  * Read and discard whole-line slash command argument.
2756  *
2757  * This *MUST* be used for inactive-branch processing of any slash command
2758  * that takes an OT_WHOLE_LINE option. Otherwise we might consume a different
2759  * amount of option text in active and inactive cases.
2760  */
2761 static void
2763 {
2764  char *arg = psql_scan_slash_option(scan_state,
2765  OT_WHOLE_LINE, NULL, false);
2766 
2767  if (arg)
2768  free(arg);
2769 }
2770 
2771 /*
2772  * Return true if the command given is a branching command.
2773  */
2774 static bool
2775 is_branching_command(const char *cmd)
2776 {
2777  return (strcmp(cmd, "if") == 0 ||
2778  strcmp(cmd, "elif") == 0 ||
2779  strcmp(cmd, "else") == 0 ||
2780  strcmp(cmd, "endif") == 0);
2781 }
2782 
2783 /*
2784  * Prepare to possibly restore query buffer to its current state
2785  * (cf. discard_query_text).
2786  *
2787  * We need to remember the length of the query buffer, and the lexer's
2788  * notion of the parenthesis nesting depth.
2789  */
2790 static void
2792  PQExpBuffer query_buf)
2793 {
2794  if (query_buf)
2795  conditional_stack_set_query_len(cstack, query_buf->len);
2797  psql_scan_get_paren_depth(scan_state));
2798 }
2799 
2800 /*
2801  * Discard any query text absorbed during an inactive conditional branch.
2802  *
2803  * We must discard data that was appended to query_buf during an inactive
2804  * \if branch. We don't have to do anything there if there's no query_buf.
2805  *
2806  * Also, reset the lexer state to the same paren depth there was before.
2807  * (The rest of its state doesn't need attention, since we could not be
2808  * inside a comment or literal or partial token.)
2809  */
2810 static void
2812  PQExpBuffer query_buf)
2813 {
2814  if (query_buf)
2815  {
2816  int new_len = conditional_stack_get_query_len(cstack);
2817 
2818  Assert(new_len >= 0 && new_len <= query_buf->len);
2819  query_buf->len = new_len;
2820  query_buf->data[new_len] = '\0';
2821  }
2822  psql_scan_set_paren_depth(scan_state,
2824 }
2825 
2826 /*
2827  * If query_buf is empty, copy previous_buf into it.
2828  *
2829  * This is used by various slash commands for which re-execution of a
2830  * previous query is a common usage. For convenience, we allow the
2831  * case of query_buf == NULL (and do nothing).
2832  */
2833 static void
2835 {
2836  if (query_buf && query_buf->len == 0)
2837  appendPQExpBufferStr(query_buf, previous_buf->data);
2838 }
2839 
2840 /*
2841  * Ask the user for a password; 'username' is the username the
2842  * password is for, if one has been explicitly specified. Returns a
2843  * malloc'd string.
2844  */
2845 static char *
2847 {
2848  char buf[100];
2849 
2850  if (username == NULL || username[0] == '\0')
2851  simple_prompt("Password: ", buf, sizeof(buf), false);
2852  else
2853  {
2854  char *prompt_text;
2855 
2856  prompt_text = psprintf(_("Password for user %s: "), username);
2857  simple_prompt(prompt_text, buf, sizeof(buf), false);
2858  free(prompt_text);
2859  }
2860  return pg_strdup(buf);
2861 }
2862 
2863 static bool
2864 param_is_newly_set(const char *old_val, const char *new_val)
2865 {
2866  if (new_val == NULL)
2867  return false;
2868 
2869  if (old_val == NULL || strcmp(old_val, new_val) != 0)
2870  return true;
2871 
2872  return false;
2873 }
2874 
2875 /* return whether the connection has 'hostaddr' in its conninfo */
2876 static bool
2878 {
2879  bool used = false;
2880  PQconninfoOption *ciopt = PQconninfo(conn);
2881 
2882  for (PQconninfoOption *p = ciopt; p->keyword != NULL; p++)
2883  {
2884  if (strcmp(p->keyword, "hostaddr") == 0 && p->val != NULL)
2885  {
2886  used = true;
2887  break;
2888  }
2889  }
2890 
2891  PQconninfoFree(ciopt);
2892  return used;
2893 }
2894 
2895 /*
2896  * do_connect -- handler for \connect
2897  *
2898  * Connects to a database with given parameters. Absent an established
2899  * connection, all parameters are required. Given -reuse-previous=off or a
2900  * connection string without -reuse-previous=on, NULL values will pass through
2901  * to PQconnectdbParams(), so the libpq defaults will be used. Otherwise, NULL
2902  * values will be replaced with the ones in the current connection.
2903  *
2904  * In interactive mode, if connection fails with the given parameters,
2905  * the old connection will be kept.
2906  */
2907 static bool
2908 do_connect(enum trivalue reuse_previous_specification,
2909  char *dbname, char *user, char *host, char *port)
2910 {
2911  PGconn *o_conn = pset.db,
2912  *n_conn;
2913  char *password = NULL;
2914  char *hostaddr = NULL;
2915  bool keep_password;
2916  bool has_connection_string;
2917  bool reuse_previous;
2919 
2920  if (!o_conn && (!dbname || !user || !host || !port))
2921  {
2922  /*
2923  * We don't know the supplied connection parameters and don't want to
2924  * connect to the wrong database by using defaults, so require all
2925  * parameters to be specified.
2926  */
2927  pg_log_error("All connection parameters must be supplied because no "
2928  "database connection exists");
2929  return false;
2930  }
2931 
2932  has_connection_string = dbname ?
2933  recognized_connection_string(dbname) : false;
2934  switch (reuse_previous_specification)
2935  {
2936  case TRI_YES:
2937  reuse_previous = true;
2938  break;
2939  case TRI_NO:
2940  reuse_previous = false;
2941  break;
2942  default:
2943  reuse_previous = !has_connection_string;
2944  break;
2945  }
2946  /* Silently ignore arguments subsequent to a connection string. */
2947  if (has_connection_string)
2948  {
2949  user = NULL;
2950  host = NULL;
2951  port = NULL;
2952  }
2953 
2954  /*
2955  * Grab missing values from the old connection. If we grab host (or host
2956  * is the same as before) and hostaddr was set, grab that too.
2957  */
2958  if (reuse_previous)
2959  {
2960  if (!user)
2961  user = PQuser(o_conn);
2962  if (host && strcmp(host, PQhost(o_conn)) == 0 &&
2963  has_hostaddr(o_conn))
2964  {
2965  hostaddr = PQhostaddr(o_conn);
2966  }
2967  if (!host)
2968  {
2969  host = PQhost(o_conn);
2970  if (has_hostaddr(o_conn))
2971  hostaddr = PQhostaddr(o_conn);
2972  }
2973  if (!port)
2974  port = PQport(o_conn);
2975  }
2976 
2977  /*
2978  * Any change in the parameters read above makes us discard the password.
2979  * We also discard it if we're to use a conninfo rather than the
2980  * positional syntax.
2981  */
2982  if (has_connection_string)
2983  keep_password = false;
2984  else
2985  keep_password =
2986  (user && PQuser(o_conn) && strcmp(user, PQuser(o_conn)) == 0) &&
2987  (host && PQhost(o_conn) && strcmp(host, PQhost(o_conn)) == 0) &&
2988  (port && PQport(o_conn) && strcmp(port, PQport(o_conn)) == 0);
2989 
2990  /*
2991  * Grab missing dbname from old connection. No password discard if this
2992  * changes: passwords aren't (usually) database-specific.
2993  */
2994  if (!dbname && reuse_previous)
2995  {
2996  initPQExpBuffer(&connstr);
2997  appendPQExpBufferStr(&connstr, "dbname=");
2998  appendConnStrVal(&connstr, PQdb(o_conn));
2999  dbname = connstr.data;
3000  /* has_connection_string=true would be a dead store */
3001  }
3002  else
3003  connstr.data = NULL;
3004 
3005  /*
3006  * If the user asked to be prompted for a password, ask for one now. If
3007  * not, use the password from the old connection, provided the username
3008  * etc have not changed. Otherwise, try to connect without a password
3009  * first, and then ask for a password if needed.
3010  *
3011  * XXX: this behavior leads to spurious connection attempts recorded in
3012  * the postmaster's log. But libpq offers no API that would let us obtain
3013  * a password and then continue with the first connection attempt.
3014  */
3015  if (pset.getPassword == TRI_YES)
3016  {
3017  /*
3018  * If a connstring or URI is provided, we can't be sure we know which
3019  * username will be used, since we haven't parsed that argument yet.
3020  * Don't risk issuing a misleading prompt. As in startup.c, it does
3021  * not seem worth working harder, since this getPassword option is
3022  * normally only used in noninteractive cases.
3023  */
3024  password = prompt_for_password(has_connection_string ? NULL : user);
3025  }
3026  else if (o_conn && keep_password)
3027  {
3028  password = PQpass(o_conn);
3029  if (password && *password)
3030  password = pg_strdup(password);
3031  else
3032  password = NULL;
3033  }
3034 
3035  while (true)
3036  {
3037 #define PARAMS_ARRAY_SIZE 9
3038  const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
3039  const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
3040  int paramnum = -1;
3041 
3042  keywords[++paramnum] = "host";
3043  values[paramnum] = host;
3044  if (hostaddr && *hostaddr)
3045  {
3046  keywords[++paramnum] = "hostaddr";
3047  values[paramnum] = hostaddr;
3048  }
3049  keywords[++paramnum] = "port";
3050  values[paramnum] = port;
3051  keywords[++paramnum] = "user";
3052  values[paramnum] = user;
3053 
3054  /*
3055  * Position in the array matters when the dbname is a connection
3056  * string, because settings in a connection string override earlier
3057  * array entries only. Thus, user= in the connection string always
3058  * takes effect, but client_encoding= often will not.
3059  *
3060  * If you change this code, also change the initial-connection code in
3061  * main(). For no good reason, a connection string password= takes
3062  * precedence in main() but not here.
3063  */
3064  keywords[++paramnum] = "dbname";
3065  values[paramnum] = dbname;
3066  keywords[++paramnum] = "password";
3067  values[paramnum] = password;
3068  keywords[++paramnum] = "fallback_application_name";
3069  values[paramnum] = pset.progname;
3070  keywords[++paramnum] = "client_encoding";
3071  values[paramnum] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto";
3072 
3073  /* add array terminator */
3074  keywords[++paramnum] = NULL;
3075  values[paramnum] = NULL;
3076 
3077  n_conn = PQconnectdbParams(keywords, values, true);
3078 
3079  pg_free(keywords);
3080  pg_free(values);
3081 
3082  /* We can immediately discard the password -- no longer needed */
3083  if (password)
3084  pg_free(password);
3085 
3086  if (PQstatus(n_conn) == CONNECTION_OK)
3087  break;
3088 
3089  /*
3090  * Connection attempt failed; either retry the connection attempt with
3091  * a new password, or give up.
3092  */
3093  if (!password && PQconnectionNeedsPassword(n_conn) && pset.getPassword != TRI_NO)
3094  {
3095  /*
3096  * Prompt for password using the username we actually connected
3097  * with --- it might've come out of "dbname" rather than "user".
3098  */
3099  password = prompt_for_password(PQuser(n_conn));
3100  PQfinish(n_conn);
3101  continue;
3102  }
3103 
3104  /*
3105  * Failed to connect to the database. In interactive mode, keep the
3106  * previous connection to the DB; in scripting mode, close our
3107  * previous connection as well.
3108  */
3110  {
3111  pg_log_info("%s", PQerrorMessage(n_conn));
3112 
3113  /* pset.db is left unmodified */
3114  if (o_conn)
3115  pg_log_info("Previous connection kept");
3116  }
3117  else
3118  {
3119  pg_log_error("\\connect: %s", PQerrorMessage(n_conn));
3120  if (o_conn)
3121  {
3122  /*
3123  * Transition to having no connection. Keep this bit in sync
3124  * with CheckConnection().
3125  */
3126  PQfinish(o_conn);
3127  pset.db = NULL;
3128  ResetCancelConn();
3129  UnsyncVariables();
3130  }
3131  }
3132 
3133  PQfinish(n_conn);
3134  if (connstr.data)
3135  termPQExpBuffer(&connstr);
3136  return false;
3137  }
3138  if (connstr.data)
3139  termPQExpBuffer(&connstr);
3140 
3141  /*
3142  * Replace the old connection with the new one, and update
3143  * connection-dependent variables. Keep the resynchronization logic in
3144  * sync with CheckConnection().
3145  */
3146  PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
3147  pset.db = n_conn;
3148  SyncVariables();
3149  connection_warnings(false); /* Must be after SyncVariables */
3150 
3151  /* Tell the user about the new connection */
3152  if (!pset.quiet)
3153  {
3154  if (!o_conn ||
3155  param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) ||
3156  param_is_newly_set(PQport(o_conn), PQport(pset.db)))
3157  {
3158  char *host = PQhost(pset.db);
3159  char *hostaddr = PQhostaddr(pset.db);
3160 
3161  /*
3162  * If the host is an absolute path, the connection is via socket
3163  * unless overridden by hostaddr
3164  */
3165  if (is_absolute_path(host))
3166  {
3167  if (hostaddr && *hostaddr)
3168  printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
3169  PQdb(pset.db), PQuser(pset.db), hostaddr, PQport(pset.db));
3170  else
3171  printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
3172  PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
3173  }
3174  else
3175  {
3176  if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
3177  printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
3178  PQdb(pset.db), PQuser(pset.db), host, hostaddr, PQport(pset.db));
3179  else
3180  printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
3181  PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
3182  }
3183  }
3184  else
3185  printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
3186  PQdb(pset.db), PQuser(pset.db));
3187  }
3188 
3189  if (o_conn)
3190  PQfinish(o_conn);
3191  return true;
3192 }
3193 
3194 
3195 void
3196 connection_warnings(bool in_startup)
3197 {
3198  if (!pset.quiet && !pset.notty)
3199  {
3200  int client_ver = PG_VERSION_NUM;
3201  char cverbuf[32];
3202  char sverbuf[32];
3203 
3204  if (pset.sversion != client_ver)
3205  {
3206  const char *server_version;
3207 
3208  /* Try to get full text form, might include "devel" etc */
3209  server_version = PQparameterStatus(pset.db, "server_version");
3210  /* Otherwise fall back on pset.sversion */
3211  if (!server_version)
3212  {
3214  sverbuf, sizeof(sverbuf));
3215  server_version = sverbuf;
3216  }
3217 
3218  printf(_("%s (%s, server %s)\n"),
3219  pset.progname, PG_VERSION, server_version);
3220  }
3221  /* For version match, only print psql banner on startup. */
3222  else if (in_startup)
3223  printf("%s (%s)\n", pset.progname, PG_VERSION);
3224 
3225  if (pset.sversion / 100 > client_ver / 100)
3226  printf(_("WARNING: %s major version %s, server major version %s.\n"
3227  " Some psql features might not work.\n"),
3228  pset.progname,
3229  formatPGVersionNumber(client_ver, false,
3230  cverbuf, sizeof(cverbuf)),
3232  sverbuf, sizeof(sverbuf)));
3233 
3234 #ifdef WIN32
3235  if (in_startup)
3236  checkWin32Codepage();
3237 #endif
3238  printSSLInfo();
3239  printGSSInfo();
3240  }
3241 }
3242 
3243 
3244 /*
3245  * printSSLInfo
3246  *
3247  * Prints information about the current SSL connection, if SSL is in use
3248  */
3249 static void
3251 {
3252  const char *protocol;
3253  const char *cipher;
3254  const char *bits;
3255  const char *compression;
3256 
3257  if (!PQsslInUse(pset.db))
3258  return; /* no SSL */
3259 
3260  protocol = PQsslAttribute(pset.db, "protocol");
3261  cipher = PQsslAttribute(pset.db, "cipher");
3262  bits = PQsslAttribute(pset.db, "key_bits");
3263  compression = PQsslAttribute(pset.db, "compression");
3264 
3265  printf(_("SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n"),
3266  protocol ? protocol : _("unknown"),
3267  cipher ? cipher : _("unknown"),
3268  bits ? bits : _("unknown"),
3269  (compression && strcmp(compression, "off") != 0) ? _("on") : _("off"));
3270 }
3271 
3272 /*
3273  * printGSSInfo
3274  *
3275  * Prints information about the current GSSAPI connection, if GSSAPI encryption is in use
3276  */
3277 static void
3279 {
3280  if (!PQgssEncInUse(pset.db))
3281  return; /* no GSSAPI encryption in use */
3282 
3283  printf(_("GSSAPI-encrypted connection\n"));
3284 }
3285 
3286 
3287 /*
3288  * checkWin32Codepage
3289  *
3290  * Prints a warning when win32 console codepage differs from Windows codepage
3291  */
3292 #ifdef WIN32
3293 static void
3294 checkWin32Codepage(void)
3295 {
3296  unsigned int wincp,
3297  concp;
3298 
3299  wincp = GetACP();
3300  concp = GetConsoleCP();
3301  if (wincp != concp)
3302  {
3303  printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
3304  " 8-bit characters might not work correctly. See psql reference\n"
3305  " page \"Notes for Windows users\" for details.\n"),
3306  concp, wincp);
3307  }
3308 }
3309 #endif
3310 
3311 
3312 /*
3313  * SyncVariables
3314  *
3315  * Make psql's internal variables agree with connection state upon
3316  * establishing a new connection.
3317  */
3318 void
3320 {
3321  char vbuf[32];
3322  const char *server_version;
3323 
3324  /* get stuff from connection */
3328 
3329  SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
3330  SetVariable(pset.vars, "USER", PQuser(pset.db));
3331  SetVariable(pset.vars, "HOST", PQhost(pset.db));
3332  SetVariable(pset.vars, "PORT", PQport(pset.db));
3334 
3335  /* this bit should match connection_warnings(): */
3336  /* Try to get full text form of version, might include "devel" etc */
3337  server_version = PQparameterStatus(pset.db, "server_version");
3338  /* Otherwise fall back on pset.sversion */
3339  if (!server_version)
3340  {
3341  formatPGVersionNumber(pset.sversion, true, vbuf, sizeof(vbuf));
3342  server_version = vbuf;
3343  }
3344  SetVariable(pset.vars, "SERVER_VERSION_NAME", server_version);
3345 
3346  snprintf(vbuf, sizeof(vbuf), "%d", pset.sversion);
3347  SetVariable(pset.vars, "SERVER_VERSION_NUM", vbuf);
3348 
3349  /* send stuff to it, too */
3352 }
3353 
3354 /*
3355  * UnsyncVariables
3356  *
3357  * Clear variables that should be not be set when there is no connection.
3358  */
3359 void
3361 {
3362  SetVariable(pset.vars, "DBNAME", NULL);
3363  SetVariable(pset.vars, "USER", NULL);
3364  SetVariable(pset.vars, "HOST", NULL);
3365  SetVariable(pset.vars, "PORT", NULL);
3366  SetVariable(pset.vars, "ENCODING", NULL);
3367  SetVariable(pset.vars, "SERVER_VERSION_NAME", NULL);
3368  SetVariable(pset.vars, "SERVER_VERSION_NUM", NULL);
3369 }
3370 
3371 
3372 /*
3373  * do_edit -- handler for \e
3374  *
3375  * If you do not specify a filename, the current query buffer will be copied
3376  * into a temporary one.
3377  */
3378 static bool
3379 editFile(const char *fname, int lineno)
3380 {
3381  const char *editorName;
3382  const char *editor_lineno_arg = NULL;
3383  char *sys;
3384  int result;
3385 
3386  Assert(fname != NULL);
3387 
3388  /* Find an editor to use */
3389  editorName = getenv("PSQL_EDITOR");
3390  if (!editorName)
3391  editorName = getenv("EDITOR");
3392  if (!editorName)
3393  editorName = getenv("VISUAL");
3394  if (!editorName)
3395  editorName = DEFAULT_EDITOR;
3396 
3397  /* Get line number argument, if we need it. */
3398  if (lineno > 0)
3399  {
3400  editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
3401 #ifdef DEFAULT_EDITOR_LINENUMBER_ARG
3402  if (!editor_lineno_arg)
3403  editor_lineno_arg = DEFAULT_EDITOR_LINENUMBER_ARG;
3404 #endif
3405  if (!editor_lineno_arg)
3406  {
3407  pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number");
3408  return false;
3409  }
3410  }
3411 
3412  /*
3413  * On Unix the EDITOR value should *not* be quoted, since it might include
3414  * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
3415  * if necessary. But this policy is not very workable on Windows, due to
3416  * severe brain damage in their command shell plus the fact that standard
3417  * program paths include spaces.
3418  */
3419 #ifndef WIN32
3420  if (lineno > 0)
3421  sys = psprintf("exec %s %s%d '%s'",
3422  editorName, editor_lineno_arg, lineno, fname);
3423  else
3424  sys = psprintf("exec %s '%s'",
3425  editorName, fname);
3426 #else
3427  if (lineno > 0)
3428  sys = psprintf("\"%s\" %s%d \"%s\"",
3429  editorName, editor_lineno_arg, lineno, fname);
3430  else
3431  sys = psprintf("\"%s\" \"%s\"",
3432  editorName, fname);
3433 #endif
3434  result = system(sys);
3435  if (result == -1)
3436  pg_log_error("could not start editor \"%s\"", editorName);
3437  else if (result == 127)
3438  pg_log_error("could not start /bin/sh");
3439  free(sys);
3440 
3441  return result == 0;
3442 }
3443 
3444 
3445 /* call this one */
3446 static bool
3447 do_edit(const char *filename_arg, PQExpBuffer query_buf,
3448  int lineno, bool *edited)
3449 {
3450  char fnametmp[MAXPGPATH];
3451  FILE *stream = NULL;
3452  const char *fname;
3453  bool error = false;
3454  int fd;
3455 
3456  struct stat before,
3457  after;
3458 
3459  if (filename_arg)
3460  fname = filename_arg;
3461  else
3462  {
3463  /* make a temp file to edit */
3464 #ifndef WIN32
3465  const char *tmpdir = getenv("TMPDIR");
3466 
3467  if (!tmpdir)
3468  tmpdir = "/tmp";
3469 #else
3470  char tmpdir[MAXPGPATH];
3471  int ret;
3472 
3473  ret = GetTempPath(MAXPGPATH, tmpdir);
3474  if (ret == 0 || ret > MAXPGPATH)
3475  {
3476  pg_log_error("could not locate temporary directory: %s",
3477  !ret ? strerror(errno) : "");
3478  return false;
3479  }
3480 
3481  /*
3482  * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
3483  * current directory to the supplied path unless we use only
3484  * backslashes, so we do that.
3485  */
3486 #endif
3487 #ifndef WIN32
3488  snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
3489  "/", (int) getpid());
3490 #else
3491  snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
3492  "" /* trailing separator already present */ , (int) getpid());
3493 #endif
3494 
3495  fname = (const char *) fnametmp;
3496 
3497  fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
3498  if (fd != -1)
3499  stream = fdopen(fd, "w");
3500 
3501  if (fd == -1 || !stream)
3502  {
3503  pg_log_error("could not open temporary file \"%s\": %m", fname);
3504  error = true;
3505  }
3506  else
3507  {
3508  unsigned int ql = query_buf->len;
3509 
3510  /* force newline-termination of what we send to editor */
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:1668
static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1120
char * gset_prefix
Definition: settings.h:95
static void usage(void)
Definition: pg_standby.c:591
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:1400
static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2368
static void ignore_boolean_expression(PsqlScanState scan_state)
Definition: command.c:2712
bool do_lo_export(const char *loid_arg, const char *filename_arg)
Definition: large_obj.c:142
static bool param_is_newly_set(const char *old_val, const char *new_val)
Definition: command.c:2864
PGconn * db
Definition: settings.h:82
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6631
void psql_scan_slash_command_end(PsqlScanState state)
EditableObjectType
Definition: command.c:49
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
static backslashResult exec_command_else(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1563
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:128
volatile bool sigint_interrupt_enabled
Definition: common.c:245
char * nullPrint
Definition: print.h:170
static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1890
static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch)
Definition: command.c:426
void print_copyright(void)
Definition: help.c:664
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
int encoding
Definition: print.h:122
#define EXIT_SUCCESS
Definition: settings.h:149
PsqlSettings pset
Definition: startup.c:31
PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
Definition: fe-connect.c:6807
void conditional_stack_set_query_len(ConditionalStack cstack, int len)
Definition: conditional.c:139
const printTextFormat * line_style
Definition: print.h:115
void SyncVariables(void)
Definition: command.c:3319
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:6596
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:591
static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1350
static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:2791
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:2941
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:2775
static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name)
Definition: command.c:2695
void ResetCancelConn(void)
Definition: cancel.c:100
printTextFormat pg_utf8format
Definition: print.c:99
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:921
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:3042
static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1233
const printTextFormat pg_asciiformat_old
Definition: print.c:77
bool do_lo_unlink(const char *loid_arg)
Definition: large_obj.c:239
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
bool recognized_connection_string(const char *connstr)
Definition: common.c:2295
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:97
void psql_scan_set_paren_depth(PsqlScanState state, int depth)
enum printFormat format
Definition: print.h:101
void PsqlVarEnumError(const char *name, const char *value, const char *suggestions)
Definition: variables.c:391
int conditional_stack_get_query_len(ConditionalStack cstack)
Definition: conditional.c:150
#define Min(x, y)
Definition: c.h:911
printTableOpt topt
Definition: print.h:169
unicode_linestyle
Definition: print.h:87
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:2593
static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:1796
static struct @145 value
static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2292
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:545
FILE * queryFout
Definition: settings.h:84
void canonicalize_path(char *path)
Definition: path.c:254
static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1964
unicode_linestyle unicode_header_linestyle
Definition: print.h:127
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4133
char * PQport(const PGconn *conn)
Definition: fe-connect.c:6550
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:1203
#define printf(...)
Definition: port.h:198
char * inputfile
Definition: settings.h:109
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:669
static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1822
static void printGSSInfo(void)
Definition: command.c:3278
NameData relname
Definition: pg_class.h:35
unsigned int Oid
Definition: postgres_ext.h:31
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6621
bool listDomains(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4133
const char * name
Definition: print.h:72
void PrintVariables(VariableSpace space)
Definition: variables.c:186
static char * read_connect_arg(PsqlScanState scan_state)
Definition: command.c:2625
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:1223
bool separator_zero
Definition: print.h:96
static int fd(const char *x, int i)
Definition: preproc-init.c:105
unicode_linestyle unicode_border_linestyle
Definition: print.h:125
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6691
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:630
char relkind
Definition: pg_class.h:81
void UnsyncVariables(void)
Definition: command.c:3360
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6489
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:247
static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2548
bool describeSubscriptions(const char *pattern, bool verbose)
Definition: describe.c:5930
static int count_lines_in_buf(PQExpBuffer buf)
Definition: command.c:4850
static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1256
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:104
char * ctv_args[4]
Definition: settings.h:99
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:2487
bool describeAggregates(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:62
unsigned short int expanded
Definition: print.h:102
static backslashResult exec_command(const char *cmd, PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:273
bool cur_cmd_interactive
Definition: settings.h:106
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:134
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:2991
static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2571
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:2130
void expand_tilde(char **filename)
Definition: common.c:2210
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:126
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:589
bool describeTableDetails(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:1366
bool tuples_only
Definition: print.h:110
bool gdesc_flag
Definition: settings.h:96
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:2745
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:998
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:6463
#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:1487
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:94
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:6497
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:6422
bool do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
Definition: command.c:3754
char * tableAttr
Definition: print.h:121
static bool editFile(const char *fname, int lineno)
Definition: command.c:3379
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:670
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
bool do_lo_import(const char *filename_arg, const char *comment_arg)
Definition: large_obj.c:176
#define atooid(x)
Definition: postgres_ext.h:42
static PQExpBuffer gather_boolean_expression(PsqlScanState scan_state)
Definition: command.c:2665
static char * prompt_for_password(const char *username)
Definition: command.c:2846
void restore_sigpipe_trap(void)
Definition: print.c:2964
static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch)
Definition: command.c:478
static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1321
bool listForeignTables(const char *pattern, bool verbose)
Definition: describe.c:5456
char * PQhostaddr(const PGconn *conn)
Definition: fe-connect.c:6537
static int port
Definition: pg_regress.c:91
char csvFieldSep[2]
Definition: print.h:118
#define DEFAULT_EDITOR
Definition: settings.h:22
static backslashResult exec_command_endif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1628
bool describePublications(const char *pattern)
Definition: describe.c:5775
static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2077
#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:1133
static backslashResult exec_command_if(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1441
static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1304
PGContextVisibility show_context
Definition: settings.h:142
char * gfname
Definition: settings.h:93
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:85
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2336
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:2811
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:6699
PGresult * last_error_result
Definition: settings.h:89
static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, int lineno, bool *edited)
Definition: command.c:3447
FILE * logfile
Definition: settings.h:115
PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
Definition: fe-connect.c:6757
bool listPublications(const char *pattern)
Definition: describe.c:5704
bool listForeignServers(const char *pattern, bool verbose)
Definition: describe.c:5313
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
ifState conditional_stack_peek(ConditionalStack cstack)
Definition: conditional.c:94
unsigned short int pager
Definition: print.h:106
static char * username
Definition: initdb.c:133
static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1165
#define InvalidOid
Definition: postgres_ext.h:36
PGVerbosity verbosity
Definition: settings.h:141
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:6514
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:2165
#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:1381
struct separator fieldSep
Definition: print.h:116
void NoticeProcessor(void *arg, const char *message)
Definition: common.c:220
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:588
bool describeAccessMethods(const char *pattern, bool verbose)
Definition: describe.c:148
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6481
const printTextFormat * get_line_style(const printTableOpt *opt)
Definition: print.c:3560
char * title
Definition: print.h:171
int pager_min_lines
Definition: print.h:108
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2754
bool default_footer
Definition: print.h:113
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:739
bool listForeignDataWrappers(const char *pattern, bool verbose)
Definition: describe.c:5230
#define DEFAULT_EDITOR_LINENUMBER_ARG
Definition: settings.h:23
const char * progname
Definition: settings.h:108
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:91
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:103
static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2050
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:2834
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:2398
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:2018
bool do_lo_list(void)
Definition: large_obj.c:274
bool numericLocale
Definition: print.h:119
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:2526
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:6665
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:2728
static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:531
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:658
void refresh_utf8format(const printTableOpt *opt)
Definition: print.c:3574
bool crosstab_flag
Definition: settings.h:98
#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:1697
#define EXIT_FAILURE
Definition: settings.h:153
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
void * arg
const printTextFormat pg_asciiformat
Definition: print.c:56
static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2314
static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1773
char * separator
Definition: print.h:95
bool listDefaultACLs(const char *pattern)
Definition: describe.c:1089
static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch)
Definition: command.c:636
static bool has_hostaddr(PGconn *conn)
Definition: command.c:2877
printFormat
Definition: print.h:28
void connection_warnings(bool in_startup)
Definition: command.c:3196
bool permissionsList(const char *pattern)
Definition: describe.c:929
struct separator recordSep
Definition: print.h:117
static void printSSLInfo(void)
Definition: command.c:3250
#define pg_log_warning(...)
Definition: pgfnames.c:24
backslashResult HandleSlashCmds(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:200
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:148
int encoding
Definition: settings.h:83
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:6578
static bool success
Definition: initdb.c:161
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:2032
static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1287
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:445
#define snprintf
Definition: port.h:192
int columns
Definition: print.h:124
PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
Definition: fe-connect.c:6745
#define _(x)
Definition: elog.c:87
bool listTSParsers(const char *pattern, bool verbose)
Definition: describe.c:4635