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