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