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