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 for (size_t i = 0; i < lengthof(pset.ctv_args); i++)
1005 OT_NORMAL, NULL, true);
1006 pset.crosstab_flag = true;
1007 status = PSQL_CMD_SEND;
1008 }
1009 else
1011
1012 return status;
1013}
1014
1015/*
1016 * \d* commands
1017 */
1018static backslashResult
1020{
1022 bool success = true;
1023
1024 if (active_branch)
1025 {
1026 char *pattern;
1027 bool show_verbose,
1029 unsigned short int save_expanded;
1030
1031 /* We don't do SQLID reduction on the pattern yet */
1033 OT_NORMAL, NULL, true);
1034
1035 show_verbose = strchr(cmd, '+') ? true : false;
1036 show_system = strchr(cmd, 'S') ? true : false;
1037
1038 /*
1039 * The 'x' option turns expanded mode on for this command only. This
1040 * is allowed in all \d* commands, except \d by itself, since \dx is a
1041 * separate command. So the 'x' option cannot appear immediately after
1042 * \d, but it can appear after \d followed by other options.
1043 */
1045 if (cmd[1] != '\0' && strchr(&cmd[2], 'x'))
1046 pset.popt.topt.expanded = 1;
1047
1048 switch (cmd[1])
1049 {
1050 case '\0':
1051 case '+':
1052 case 'S':
1053 if (pattern)
1055 else
1056 /* standard listing of interesting things */
1058 break;
1059 case 'A':
1060 {
1061 char *pattern2 = NULL;
1062
1063 if (pattern && cmd[2] != '\0' && cmd[2] != '+' && cmd[2] != 'x')
1065
1066 switch (cmd[2])
1067 {
1068 case '\0':
1069 case '+':
1070 case 'x':
1072 break;
1073 case 'c':
1075 break;
1076 case 'f':
1078 break;
1079 case 'o':
1081 break;
1082 case 'p':
1084 break;
1085 default:
1086 status = PSQL_CMD_UNKNOWN;
1087 break;
1088 }
1089
1090 free(pattern2);
1091 }
1092 break;
1093 case 'a':
1095 break;
1096 case 'b':
1098 break;
1099 case 'c':
1100 if (strncmp(cmd, "dconfig", 7) == 0)
1103 show_system);
1104 else
1105 success = listConversions(pattern,
1107 show_system);
1108 break;
1109 case 'C':
1110 success = listCasts(pattern, show_verbose);
1111 break;
1112 case 'd':
1113 if (strncmp(cmd, "ddp", 3) == 0)
1114 success = listDefaultACLs(pattern);
1115 else
1117 break;
1118 case 'D':
1120 break;
1121 case 'f': /* function subsystem */
1122 switch (cmd[2])
1123 {
1124 case '\0':
1125 case '+':
1126 case 'S':
1127 case 'a':
1128 case 'n':
1129 case 'p':
1130 case 't':
1131 case 'w':
1132 case 'x':
1133 success = exec_command_dfo(scan_state, cmd, pattern,
1135 break;
1136 default:
1137 status = PSQL_CMD_UNKNOWN;
1138 break;
1139 }
1140 break;
1141 case 'g':
1142 /* no longer distinct from \du */
1144 break;
1145 case 'l':
1147 break;
1148 case 'L':
1150 break;
1151 case 'n':
1153 break;
1154 case 'o':
1155 success = exec_command_dfo(scan_state, cmd, pattern,
1157 break;
1158 case 'O':
1160 break;
1161 case 'p':
1163 break;
1164 case 'P':
1165 {
1166 switch (cmd[2])
1167 {
1168 case '\0':
1169 case '+':
1170 case 't':
1171 case 'i':
1172 case 'n':
1173 case 'x':
1174 success = listPartitionedTables(&cmd[2], pattern, show_verbose);
1175 break;
1176 default:
1177 status = PSQL_CMD_UNKNOWN;
1178 break;
1179 }
1180 }
1181 break;
1182 case 'T':
1184 break;
1185 case 't':
1186 case 'v':
1187 case 'm':
1188 case 'i':
1189 case 's':
1190 case 'E':
1191 case 'G':
1192 success = listTables(&cmd[1], pattern, show_verbose, show_system);
1193 break;
1194 case 'r':
1195 if (cmd[2] == 'd' && cmd[3] == 's')
1196 {
1197 char *pattern2 = NULL;
1198
1199 if (pattern)
1201 OT_NORMAL, NULL, true);
1203
1204 free(pattern2);
1205 }
1206 else if (cmd[2] == 'g')
1208 else
1209 status = PSQL_CMD_UNKNOWN;
1210 break;
1211 case 'R':
1212 switch (cmd[2])
1213 {
1214 case 'p':
1215 if (show_verbose)
1216 success = describePublications(pattern);
1217 else
1218 success = listPublications(pattern);
1219 break;
1220 case 's':
1222 break;
1223 default:
1224 status = PSQL_CMD_UNKNOWN;
1225 }
1226 break;
1227 case 'u':
1229 break;
1230 case 'F': /* text search subsystem */
1231 switch (cmd[2])
1232 {
1233 case '\0':
1234 case '+':
1235 case 'x':
1237 break;
1238 case 'p':
1240 break;
1241 case 'd':
1243 break;
1244 case 't':
1246 break;
1247 default:
1248 status = PSQL_CMD_UNKNOWN;
1249 break;
1250 }
1251 break;
1252 case 'e': /* SQL/MED subsystem */
1253 switch (cmd[2])
1254 {
1255 case 's':
1257 break;
1258 case 'u':
1260 break;
1261 case 'w':
1263 break;
1264 case 't':
1266 break;
1267 default:
1268 status = PSQL_CMD_UNKNOWN;
1269 break;
1270 }
1271 break;
1272 case 'x': /* Extensions */
1273 if (show_verbose)
1274 success = listExtensionContents(pattern);
1275 else
1276 success = listExtensions(pattern);
1277 break;
1278 case 'X': /* Extended Statistics */
1280 break;
1281 case 'y': /* Event Triggers */
1283 break;
1284 default:
1285 status = PSQL_CMD_UNKNOWN;
1286 }
1287
1288 /* Restore original expanded mode */
1290
1291 free(pattern);
1292 }
1293 else
1295
1296 if (!success)
1297 status = PSQL_CMD_ERROR;
1298
1299 return status;
1300}
1301
1302/* \df and \do; messy enough to split out of exec_command_d */
1303static bool
1305 const char *pattern,
1306 bool show_verbose, bool show_system)
1307{
1308 bool success;
1310 int num_arg_patterns = 0;
1311
1312 /* Collect argument-type patterns too */
1313 if (pattern) /* otherwise it was just \df or \do */
1314 {
1315 char *ap;
1316
1318 OT_NORMAL, NULL, true)) != NULL)
1319 {
1322 break; /* protect limited-size array */
1323 }
1324 }
1325
1326 if (cmd[1] == 'f')
1327 success = describeFunctions(&cmd[2], pattern,
1330 else
1331 success = describeOperators(pattern,
1334
1335 while (--num_arg_patterns >= 0)
1337
1338 return success;
1339}
1340
1341/*
1342 * \e or \edit -- edit the current query buffer, or edit a file and
1343 * make it the query buffer
1344 */
1345static backslashResult
1348{
1350
1351 if (active_branch)
1352 {
1353 if (!query_buf)
1354 {
1355 pg_log_error("no query buffer");
1356 status = PSQL_CMD_ERROR;
1357 }
1358 else
1359 {
1360 char *fname;
1361 char *ln = NULL;
1362 int lineno = -1;
1363
1365 OT_NORMAL, NULL, true);
1366 if (fname)
1367 {
1368 /* try to get separate lineno arg */
1370 OT_NORMAL, NULL, true);
1371 if (ln == NULL)
1372 {
1373 /* only one arg; maybe it is lineno not fname */
1374 if (fname[0] &&
1375 strspn(fname, "0123456789") == strlen(fname))
1376 {
1377 /* all digits, so assume it is lineno */
1378 ln = fname;
1379 fname = NULL;
1380 }
1381 }
1382 }
1383 if (ln)
1384 {
1385 lineno = atoi(ln);
1386 if (lineno < 1)
1387 {
1388 pg_log_error("invalid line number: %s", ln);
1389 status = PSQL_CMD_ERROR;
1390 }
1391 }
1392 if (status != PSQL_CMD_ERROR)
1393 {
1394 bool discard_on_quit;
1395
1396 expand_tilde(&fname);
1397 if (fname)
1398 {
1400 /* Always clear buffer if the file isn't modified */
1401 discard_on_quit = true;
1402 }
1403 else
1404 {
1405 /*
1406 * If query_buf is empty, recall previous query for
1407 * editing. But in that case, the query buffer should be
1408 * emptied if editing doesn't modify the file.
1409 */
1411 previous_buf);
1412 }
1413
1414 if (do_edit(fname, query_buf, lineno, discard_on_quit, NULL))
1415 status = PSQL_CMD_NEWEDIT;
1416 else
1417 status = PSQL_CMD_ERROR;
1418 }
1419
1420 /*
1421 * On error while editing or if specifying an incorrect line
1422 * number, reset the query buffer.
1423 */
1424 if (status == PSQL_CMD_ERROR)
1426
1427 free(fname);
1428 free(ln);
1429 }
1430 }
1431 else
1433
1434 return status;
1435}
1436
1437/*
1438 * \ef/\ev -- edit the named function/view, or
1439 * present a blank CREATE FUNCTION/VIEW template if no argument is given
1440 */
1441static backslashResult
1443 PQExpBuffer query_buf, bool is_func)
1444{
1446
1447 if (active_branch)
1448 {
1451 NULL, true);
1452 int lineno = -1;
1453
1454 if (!query_buf)
1455 {
1456 pg_log_error("no query buffer");
1457 status = PSQL_CMD_ERROR;
1458 }
1459 else
1460 {
1463
1465 if (lineno == 0)
1466 {
1467 /* error already reported */
1468 status = PSQL_CMD_ERROR;
1469 }
1470 else if (!obj_desc)
1471 {
1472 /* set up an empty command to fill in */
1474 if (is_func)
1476 "CREATE FUNCTION ( )\n"
1477 " RETURNS \n"
1478 " LANGUAGE \n"
1479 " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
1480 "AS $function$\n"
1481 "\n$function$\n");
1482 else
1484 "CREATE VIEW AS\n"
1485 " SELECT \n"
1486 " -- something...\n");
1487 }
1488 else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
1489 {
1490 /* error already reported */
1491 status = PSQL_CMD_ERROR;
1492 }
1494 {
1495 /* error already reported */
1496 status = PSQL_CMD_ERROR;
1497 }
1498 else if (is_func && lineno > 0)
1499 {
1500 /*
1501 * lineno "1" should correspond to the first line of the
1502 * function body. We expect that pg_get_functiondef() will
1503 * emit that on a line beginning with "AS ", "BEGIN ", or
1504 * "RETURN ", and that there can be no such line before the
1505 * real start of the function body. Increment lineno by the
1506 * number of lines before that line, so that it becomes
1507 * relative to the first line of the function definition.
1508 */
1509 const char *lines = query_buf->data;
1510
1511 while (*lines != '\0')
1512 {
1513 if (strncmp(lines, "AS ", 3) == 0 ||
1514 strncmp(lines, "BEGIN ", 6) == 0 ||
1515 strncmp(lines, "RETURN ", 7) == 0)
1516 break;
1517 lineno++;
1518 /* find start of next line */
1519 lines = strchr(lines, '\n');
1520 if (!lines)
1521 break;
1522 lines++;
1523 }
1524 }
1525 }
1526
1527 if (status != PSQL_CMD_ERROR)
1528 {
1529 bool edited = false;
1530
1531 if (!do_edit(NULL, query_buf, lineno, true, &edited))
1532 status = PSQL_CMD_ERROR;
1533 else if (!edited)
1534 puts(_("No changes"));
1535 else
1536 status = PSQL_CMD_NEWEDIT;
1537 }
1538
1539 /*
1540 * On error while doing object lookup or while editing, or if
1541 * specifying an incorrect line number, reset the query buffer.
1542 */
1543 if (status == PSQL_CMD_ERROR)
1545
1546 free(obj_desc);
1547 }
1548 else
1550
1551 return status;
1552}
1553
1554/*
1555 * \echo, \qecho, and \warn -- echo arguments to stdout, query output, or stderr
1556 */
1557static backslashResult
1559{
1560 if (active_branch)
1561 {
1562 char *value;
1563 char quoted;
1564 bool no_newline = false;
1565 bool first = true;
1566 FILE *fout;
1567
1568 if (strcmp(cmd, "qecho") == 0)
1570 else if (strcmp(cmd, "warn") == 0)
1571 fout = stderr;
1572 else
1573 fout = stdout;
1574
1576 OT_NORMAL, &quoted, false)))
1577 {
1578 if (first && !no_newline && !quoted && strcmp(value, "-n") == 0)
1579 no_newline = true;
1580 else
1581 {
1582 if (first)
1583 first = false;
1584 else
1585 fputc(' ', fout);
1586 fputs(value, fout);
1587 }
1588 free(value);
1589 }
1590 if (!no_newline)
1591 fputs("\n", fout);
1592 }
1593 else
1595
1596 return PSQL_CMD_SKIP_LINE;
1597}
1598
1599/*
1600 * \encoding -- set/show client side encoding
1601 */
1602static backslashResult
1604{
1605 if (active_branch)
1606 {
1608 OT_NORMAL, NULL, false);
1609
1610 if (!encoding)
1611 {
1612 /* show encoding */
1614 }
1615 else
1616 {
1617 /* set encoding */
1618 if (PQsetClientEncoding(pset.db, encoding) == -1)
1619 pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding);
1620 else
1621 {
1622 /* save encoding info into psql internal data */
1626 SetVariable(pset.vars, "ENCODING",
1628 }
1629 free(encoding);
1630 }
1631 }
1632 else
1634
1635 return PSQL_CMD_SKIP_LINE;
1636}
1637
1638/*
1639 * \errverbose -- display verbose message from last failed query
1640 */
1641static backslashResult
1643{
1644 if (active_branch)
1645 {
1647 {
1648 char *msg;
1649
1653 if (msg)
1654 {
1655 pg_log_error("%s", msg);
1656 PQfreemem(msg);
1657 }
1658 else
1659 puts(_("out of memory"));
1660 }
1661 else
1662 puts(_("There is no previous error."));
1663 }
1664
1665 return PSQL_CMD_SKIP_LINE;
1666}
1667
1668/*
1669 * \f -- change field separator
1670 */
1671static backslashResult
1673{
1674 bool success = true;
1675
1676 if (active_branch)
1677 {
1678 char *fname = psql_scan_slash_option(scan_state,
1679 OT_NORMAL, NULL, false);
1680
1681 success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
1682 free(fname);
1683 }
1684 else
1686
1688}
1689
1690/*
1691 * \flush -- call PQflush() on the connection
1692 */
1693static backslashResult
1695{
1697
1698 if (active_branch)
1699 {
1701 status = PSQL_CMD_SEND;
1702 }
1703 else
1705
1706 return status;
1707}
1708
1709/*
1710 * \flushrequest -- call PQsendFlushRequest() on the connection
1711 */
1712static backslashResult
1714{
1716
1717 if (active_branch)
1718 {
1720 status = PSQL_CMD_SEND;
1721 }
1722 else
1724
1725 return status;
1726}
1727
1728/*
1729 * \g [(pset-option[=pset-value] ...)] [filename/shell-command]
1730 * \gx [(pset-option[=pset-value] ...)] [filename/shell-command]
1731 *
1732 * Send the current query. If pset options are specified, they are made
1733 * active just for this query. If a filename or pipe command is given,
1734 * the query output goes there. \gx implicitly sets "expanded=on" along
1735 * with any other pset options that are specified.
1736 */
1737static backslashResult
1739{
1741 char *fname;
1742
1743 /*
1744 * Because the option processing for this is fairly complicated, we do it
1745 * and then decide whether the branch is active.
1746 */
1748 OT_FILEPIPE, NULL, false);
1749
1750 if (fname && fname[0] == '(')
1751 {
1752 /* Consume pset options through trailing ')' ... */
1753 status = process_command_g_options(fname + 1, scan_state,
1754 active_branch, cmd);
1755 free(fname);
1756 /* ... and again attempt to scan the filename. */
1758 OT_FILEPIPE, NULL, false);
1759 }
1760
1761 if (status == PSQL_CMD_SKIP_LINE && active_branch)
1762 {
1764 {
1765 pg_log_error("\\%s not allowed in pipeline mode", cmd);
1767 free(fname);
1768 return PSQL_CMD_ERROR;
1769 }
1770
1771 if (!fname)
1772 pset.gfname = NULL;
1773 else
1774 {
1775 expand_tilde(&fname);
1776 pset.gfname = pg_strdup(fname);
1777 }
1778 if (strcmp(cmd, "gx") == 0)
1779 {
1780 /* save settings if not done already, then force expanded=on */
1781 if (pset.gsavepopt == NULL)
1783 pset.popt.topt.expanded = 1;
1784 }
1785 status = PSQL_CMD_SEND;
1786 }
1787
1788 free(fname);
1789
1790 return status;
1791}
1792
1793/*
1794 * Process parenthesized pset options for \g
1795 *
1796 * Note: okay to modify first_option, but not to free it; caller does that
1797 */
1798static backslashResult
1800 bool active_branch, const char *cmd)
1801{
1802 bool success = true;
1803 bool found_r_paren = false;
1804
1805 do
1806 {
1807 char *option;
1808 size_t optlen;
1809
1810 /* If not first time through, collect a new option */
1811 if (first_option)
1813 else
1814 {
1816 OT_NORMAL, NULL, false);
1817 if (!option)
1818 {
1819 if (active_branch)
1820 {
1821 pg_log_error("\\%s: missing right parenthesis", cmd);
1822 success = false;
1823 }
1824 break;
1825 }
1826 }
1827
1828 /* Check for terminating right paren, and remove it from string */
1829 optlen = strlen(option);
1830 if (optlen > 0 && option[optlen - 1] == ')')
1831 {
1832 option[--optlen] = '\0';
1833 found_r_paren = true;
1834 }
1835
1836 /* If there was anything besides parentheses, parse/execute it */
1837 if (optlen > 0)
1838 {
1839 /* We can have either "name" or "name=value" */
1840 char *valptr = strchr(option, '=');
1841
1842 if (valptr)
1843 *valptr++ = '\0';
1844 if (active_branch)
1845 {
1846 /* save settings if not done already, then apply option */
1847 if (pset.gsavepopt == NULL)
1849 success &= do_pset(option, valptr, &pset.popt, true);
1850 }
1851 }
1852
1853 /* Clean up after this option. We should not free first_option. */
1854 if (first_option)
1856 else
1857 free(option);
1858 } while (!found_r_paren);
1859
1860 /* If we failed after already changing some options, undo side-effects */
1862 {
1865 }
1866
1868}
1869
1870/*
1871 * \gdesc -- describe query result
1872 */
1873static backslashResult
1875{
1877
1878 if (active_branch)
1879 {
1880 pset.gdesc_flag = true;
1881 status = PSQL_CMD_SEND;
1882 }
1883
1884 return status;
1885}
1886
1887/*
1888 * \getenv -- set variable from environment variable
1889 */
1890static backslashResult
1892 const char *cmd)
1893{
1894 bool success = true;
1895
1896 if (active_branch)
1897 {
1899 OT_NORMAL, NULL, false);
1900 char *envvar = psql_scan_slash_option(scan_state,
1901 OT_NORMAL, NULL, false);
1902
1903 if (!myvar || !envvar)
1904 {
1905 pg_log_error("\\%s: missing required argument", cmd);
1906 success = false;
1907 }
1908 else
1909 {
1910 char *envval = getenv(envvar);
1911
1913 success = false;
1914 }
1915 free(myvar);
1916 free(envvar);
1917 }
1918 else
1920
1922}
1923
1924/*
1925 * \getresults -- read results
1926 */
1927static backslashResult
1929{
1931
1932 if (active_branch)
1933 {
1934 char *opt;
1935 int num_results;
1936
1938 status = PSQL_CMD_SEND;
1940
1942 if (opt != NULL)
1943 {
1944 num_results = atoi(opt);
1945 if (num_results < 0)
1946 {
1947 pg_log_error("\\getresults: invalid number of requested results");
1948 return PSQL_CMD_ERROR;
1949 }
1951 }
1952 }
1953 else
1955
1956 return status;
1957}
1958
1959
1960/*
1961 * \gexec -- send query and execute each field of result
1962 */
1963static backslashResult
1965{
1967
1968 if (active_branch)
1969 {
1971 {
1972 pg_log_error("\\%s not allowed in pipeline mode", "gexec");
1974 return PSQL_CMD_ERROR;
1975 }
1976 pset.gexec_flag = true;
1977 status = PSQL_CMD_SEND;
1978 }
1979
1980 return status;
1981}
1982
1983/*
1984 * \gset [prefix] -- send query and store result into variables
1985 */
1986static backslashResult
1988{
1990
1991 if (active_branch)
1992 {
1993 char *prefix = psql_scan_slash_option(scan_state,
1994 OT_NORMAL, NULL, false);
1995
1997 {
1998 pg_log_error("\\%s not allowed in pipeline mode", "gset");
2000 return PSQL_CMD_ERROR;
2001 }
2002
2003 if (prefix)
2004 pset.gset_prefix = prefix;
2005 else
2006 {
2007 /* we must set a non-NULL prefix to trigger storing */
2009 }
2010 /* gset_prefix is freed later */
2011 status = PSQL_CMD_SEND;
2012 }
2013 else
2015
2016 return status;
2017}
2018
2019/*
2020 * \help [topic] -- print help about SQL commands
2021 */
2022static backslashResult
2024{
2025 if (active_branch)
2026 {
2028 OT_WHOLE_LINE, NULL, true);
2029
2030 helpSQL(opt, pset.popt.topt.pager);
2031 free(opt);
2032 }
2033 else
2035
2036 return PSQL_CMD_SKIP_LINE;
2037}
2038
2039/*
2040 * \H and \html -- toggle HTML formatting
2041 */
2042static backslashResult
2044{
2045 bool success = true;
2046
2047 if (active_branch)
2048 {
2050 success = do_pset("format", "html", &pset.popt, pset.quiet);
2051 else
2052 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
2053 }
2054
2056}
2057
2058/*
2059 * \i and \ir -- include a file
2060 */
2061static backslashResult
2063{
2064 bool success = true;
2065
2066 if (active_branch)
2067 {
2068 char *fname = psql_scan_slash_option(scan_state,
2069 OT_NORMAL, NULL, true);
2070
2071 if (!fname)
2072 {
2073 pg_log_error("\\%s: missing required argument", cmd);
2074 success = false;
2075 }
2076 else
2077 {
2078 bool include_relative;
2079
2080 include_relative = (strcmp(cmd, "ir") == 0
2081 || strcmp(cmd, "include_relative") == 0);
2082 expand_tilde(&fname);
2084 free(fname);
2085 }
2086 }
2087 else
2089
2091}
2092
2093/*
2094 * \if <expr> -- beginning of an \if..\endif block
2095 *
2096 * <expr> is parsed as a boolean expression. Invalid expressions will emit a
2097 * warning and be treated as false. Statements that follow a false expression
2098 * will be parsed but ignored. Note that in the case where an \if statement
2099 * is itself within an inactive section of a block, then the entire inner
2100 * \if..\endif block will be parsed but ignored.
2101 */
2102static backslashResult
2105{
2106 if (conditional_active(cstack))
2107 {
2108 /*
2109 * First, push a new active stack entry; this ensures that the lexer
2110 * will perform variable substitution and backtick evaluation while
2111 * scanning the expression. (That should happen anyway, since we know
2112 * we're in an active outer branch, but let's be sure.)
2113 */
2115
2116 /* Remember current query state in case we need to restore later */
2118
2119 /*
2120 * Evaluate the expression; if it's false, change to inactive state.
2121 */
2122 if (!is_true_boolean_expression(scan_state, "\\if expression"))
2124 }
2125 else
2126 {
2127 /*
2128 * We're within an inactive outer branch, so this entire \if block
2129 * will be ignored. We don't want to evaluate the expression, so push
2130 * the "ignored" stack state before scanning it.
2131 */
2133
2134 /* Remember current query state in case we need to restore later */
2136
2138 }
2139
2140 return PSQL_CMD_SKIP_LINE;
2141}
2142
2143/*
2144 * \elif <expr> -- alternative branch in an \if..\endif block
2145 *
2146 * <expr> is evaluated the same as in \if <expr>.
2147 */
2148static backslashResult
2151{
2152 bool success = true;
2153
2154 switch (conditional_stack_peek(cstack))
2155 {
2156 case IFSTATE_TRUE:
2157
2158 /*
2159 * Just finished active branch of this \if block. Update saved
2160 * state so we will keep whatever data was put in query_buf by the
2161 * active branch.
2162 */
2164
2165 /*
2166 * Discard \elif expression and ignore the rest until \endif.
2167 * Switch state before reading expression to ensure proper lexer
2168 * behavior.
2169 */
2172 break;
2173 case IFSTATE_FALSE:
2174
2175 /*
2176 * Discard any query text added by the just-skipped branch.
2177 */
2179
2180 /*
2181 * Have not yet found a true expression in this \if block, so this
2182 * might be the first. We have to change state before examining
2183 * the expression, or the lexer won't do the right thing.
2184 */
2186 if (!is_true_boolean_expression(scan_state, "\\elif expression"))
2188 break;
2189 case IFSTATE_IGNORED:
2190
2191 /*
2192 * Discard any query text added by the just-skipped branch.
2193 */
2195
2196 /*
2197 * Skip expression and move on. Either the \if block already had
2198 * an active section, or whole block is being skipped.
2199 */
2201 break;
2202 case IFSTATE_ELSE_TRUE:
2203 case IFSTATE_ELSE_FALSE:
2204 pg_log_error("\\elif: cannot occur after \\else");
2205 success = false;
2206 break;
2207 case IFSTATE_NONE:
2208 /* no \if to elif from */
2209 pg_log_error("\\elif: no matching \\if");
2210 success = false;
2211 break;
2212 }
2213
2215}
2216
2217/*
2218 * \else -- final alternative in an \if..\endif block
2219 *
2220 * Statements within an \else branch will only be executed if
2221 * all previous \if and \elif expressions evaluated to false
2222 * and the block was not itself being ignored.
2223 */
2224static backslashResult
2227{
2228 bool success = true;
2229
2230 switch (conditional_stack_peek(cstack))
2231 {
2232 case IFSTATE_TRUE:
2233
2234 /*
2235 * Just finished active branch of this \if block. Update saved
2236 * state so we will keep whatever data was put in query_buf by the
2237 * active branch.
2238 */
2240
2241 /* Now skip the \else branch */
2243 break;
2244 case IFSTATE_FALSE:
2245
2246 /*
2247 * Discard any query text added by the just-skipped branch.
2248 */
2250
2251 /*
2252 * We've not found any true \if or \elif expression, so execute
2253 * the \else branch.
2254 */
2256 break;
2257 case IFSTATE_IGNORED:
2258
2259 /*
2260 * Discard any query text added by the just-skipped branch.
2261 */
2263
2264 /*
2265 * Either we previously processed the active branch of this \if,
2266 * or the whole \if block is being skipped. Either way, skip the
2267 * \else branch.
2268 */
2270 break;
2271 case IFSTATE_ELSE_TRUE:
2272 case IFSTATE_ELSE_FALSE:
2273 pg_log_error("\\else: cannot occur after \\else");
2274 success = false;
2275 break;
2276 case IFSTATE_NONE:
2277 /* no \if to else from */
2278 pg_log_error("\\else: no matching \\if");
2279 success = false;
2280 break;
2281 }
2282
2284}
2285
2286/*
2287 * \endif -- ends an \if...\endif block
2288 */
2289static backslashResult
2292{
2293 bool success = true;
2294
2295 switch (conditional_stack_peek(cstack))
2296 {
2297 case IFSTATE_TRUE:
2298 case IFSTATE_ELSE_TRUE:
2299 /* Close the \if block, keeping the query text */
2301 Assert(success);
2302 break;
2303 case IFSTATE_FALSE:
2304 case IFSTATE_IGNORED:
2305 case IFSTATE_ELSE_FALSE:
2306
2307 /*
2308 * Discard any query text added by the just-skipped branch.
2309 */
2311
2312 /* Close the \if block */
2314 Assert(success);
2315 break;
2316 case IFSTATE_NONE:
2317 /* no \if to end */
2318 pg_log_error("\\endif: no matching \\if");
2319 success = false;
2320 break;
2321 }
2322
2324}
2325
2326/*
2327 * \l -- list databases
2328 */
2329static backslashResult
2331{
2332 bool success = true;
2333
2334 if (active_branch)
2335 {
2336 char *pattern;
2337 bool show_verbose;
2338 unsigned short int save_expanded;
2339
2341 OT_NORMAL, NULL, true);
2342
2343 show_verbose = strchr(cmd, '+') ? true : false;
2344
2345 /* if 'x' option specified, force expanded mode */
2347 if (strchr(cmd, 'x'))
2348 pset.popt.topt.expanded = 1;
2349
2350 success = listAllDbs(pattern, show_verbose);
2351
2352 /* restore original expanded mode */
2354
2355 free(pattern);
2356 }
2357 else
2359
2361}
2362
2363/*
2364 * \lo_* -- large object operations
2365 */
2366static backslashResult
2368{
2370 bool success = true;
2371
2372 if (active_branch)
2373 {
2374 char *opt1,
2375 *opt2;
2376
2378 OT_NORMAL, NULL, true);
2380 OT_NORMAL, NULL, true);
2381
2382 if (strcmp(cmd + 3, "export") == 0)
2383 {
2384 if (!opt2)
2385 {
2386 pg_log_error("\\%s: missing required argument", cmd);
2387 success = false;
2388 }
2389 else
2390 {
2393 }
2394 }
2395
2396 else if (strcmp(cmd + 3, "import") == 0)
2397 {
2398 if (!opt1)
2399 {
2400 pg_log_error("\\%s: missing required argument", cmd);
2401 success = false;
2402 }
2403 else
2404 {
2407 }
2408 }
2409
2410 else if (strncmp(cmd + 3, "list", 4) == 0)
2411 {
2412 bool show_verbose;
2413 unsigned short int save_expanded;
2414
2415 show_verbose = strchr(cmd, '+') ? true : false;
2416
2417 /* if 'x' option specified, force expanded mode */
2419 if (strchr(cmd, 'x'))
2420 pset.popt.topt.expanded = 1;
2421
2423
2424 /* restore original expanded mode */
2426 }
2427
2428 else if (strcmp(cmd + 3, "unlink") == 0)
2429 {
2430 if (!opt1)
2431 {
2432 pg_log_error("\\%s: missing required argument", cmd);
2433 success = false;
2434 }
2435 else
2437 }
2438
2439 else
2440 status = PSQL_CMD_UNKNOWN;
2441
2442 free(opt1);
2443 free(opt2);
2444 }
2445 else
2447
2448 if (!success)
2449 status = PSQL_CMD_ERROR;
2450
2451 return status;
2452}
2453
2454/*
2455 * \o -- set query output
2456 */
2457static backslashResult
2459{
2460 bool success = true;
2461
2462 if (active_branch)
2463 {
2464 char *fname = psql_scan_slash_option(scan_state,
2465 OT_FILEPIPE, NULL, true);
2466
2467 expand_tilde(&fname);
2468 success = setQFout(fname);
2469 free(fname);
2470 }
2471 else
2473
2475}
2476
2477/*
2478 * \p -- print the current query buffer
2479 */
2480static backslashResult
2483{
2484 if (active_branch)
2485 {
2486 /*
2487 * We want to print the same thing \g would execute, but not to change
2488 * the query buffer state; so we can't use copy_previous_query().
2489 * Also, beware of possibility that buffer pointers are NULL.
2490 */
2491 if (query_buf && query_buf->len > 0)
2492 puts(query_buf->data);
2493 else if (previous_buf && previous_buf->len > 0)
2494 puts(previous_buf->data);
2495 else if (!pset.quiet)
2496 puts(_("Query buffer is empty."));
2497 fflush(stdout);
2498 }
2499
2500 return PSQL_CMD_SKIP_LINE;
2501}
2502
2503/*
2504 * \parse -- parse query
2505 */
2506static backslashResult
2508 const char *cmd)
2509{
2511
2512 if (active_branch)
2513 {
2515 OT_NORMAL, NULL, false);
2516
2518
2519 if (!opt)
2520 {
2521 pg_log_error("\\%s: missing required argument", cmd);
2522 status = PSQL_CMD_ERROR;
2523 }
2524 else
2525 {
2526 pset.stmtName = opt;
2528 status = PSQL_CMD_SEND;
2529 }
2530 }
2531 else
2533
2534 return status;
2535}
2536
2537/*
2538 * \password -- set user password
2539 */
2540static backslashResult
2542{
2543 bool success = true;
2544
2545 if (active_branch)
2546 {
2548 OT_SQLID, NULL, true);
2549 char *pw1 = NULL;
2550 char *pw2 = NULL;
2553
2554 if (user == NULL)
2555 {
2556 /* By default, the command applies to CURRENT_USER */
2557 PGresult *res;
2558
2559 res = PSQLexec("SELECT CURRENT_USER");
2560 if (!res)
2561 return PSQL_CMD_ERROR;
2562
2563 user = pg_strdup(PQgetvalue(res, 0, 0));
2564 PQclear(res);
2565 }
2566
2567 /* Set up to let SIGINT cancel simple_prompt_extended() */
2570 prompt_ctx.canceled = false;
2571
2573 printfPQExpBuffer(&buf, _("Enter new password for user \"%s\": "), user);
2574
2575 pw1 = simple_prompt_extended(buf.data, false, &prompt_ctx);
2576 if (!prompt_ctx.canceled)
2577 pw2 = simple_prompt_extended("Enter it again: ", false, &prompt_ctx);
2578
2579 if (prompt_ctx.canceled)
2580 {
2581 /* fail silently */
2582 success = false;
2583 }
2584 else if (strcmp(pw1, pw2) != 0)
2585 {
2586 pg_log_error("Passwords didn't match.");
2587 success = false;
2588 }
2589 else
2590 {
2592
2593 if (PQresultStatus(res) != PGRES_COMMAND_OK)
2594 {
2596 success = false;
2597 }
2598
2599 PQclear(res);
2600 }
2601
2602 pg_free(user);
2603 free(pw1);
2604 free(pw2);
2606 }
2607 else
2609
2611}
2612
2613/*
2614 * \prompt -- prompt and set variable
2615 */
2616static backslashResult
2618 const char *cmd)
2619{
2620 bool success = true;
2621
2622 if (active_branch)
2623 {
2624 char *opt,
2625 *prompt_text = NULL;
2626 char *arg1,
2627 *arg2;
2628
2631
2632 if (!arg1)
2633 {
2634 pg_log_error("\\%s: missing required argument", cmd);
2635 success = false;
2636 }
2637 else
2638 {
2639 char *result;
2641
2642 /* Set up to let SIGINT cancel simple_prompt_extended() */
2645 prompt_ctx.canceled = false;
2646
2647 if (arg2)
2648 {
2649 prompt_text = arg1;
2650 opt = arg2;
2651 }
2652 else
2653 opt = arg1;
2654
2655 if (!pset.inputfile)
2656 {
2658 }
2659 else
2660 {
2661 if (prompt_text)
2662 {
2663 fputs(prompt_text, stdout);
2664 fflush(stdout);
2665 }
2667 if (!result)
2668 {
2669 pg_log_error("\\%s: could not read value for variable",
2670 cmd);
2671 success = false;
2672 }
2673 }
2674
2675 if (prompt_ctx.canceled ||
2676 (result && !SetVariable(pset.vars, opt, result)))
2677 success = false;
2678
2679 free(result);
2681 free(opt);
2682 }
2683 }
2684 else
2686
2688}
2689
2690/*
2691 * \pset -- set printing parameters
2692 */
2693static backslashResult
2695{
2696 bool success = true;
2697
2698 if (active_branch)
2699 {
2701 OT_NORMAL, NULL, false);
2703 OT_NORMAL, NULL, false);
2704
2705 if (!opt0)
2706 {
2707 /* list all variables */
2708
2709 int i;
2710 static const char *const my_list[] = {
2711 "border", "columns", "csv_fieldsep",
2712 "display_false", "display_true", "expanded", "fieldsep",
2713 "fieldsep_zero", "footer", "format", "linestyle", "null",
2714 "numericlocale", "pager", "pager_min_lines",
2715 "recordsep", "recordsep_zero",
2716 "tableattr", "title", "tuples_only",
2717 "unicode_border_linestyle",
2718 "unicode_column_linestyle",
2719 "unicode_header_linestyle",
2720 "xheader_width",
2721 NULL
2722 };
2723
2724 for (i = 0; my_list[i] != NULL; i++)
2725 {
2726 char *val = pset_value_string(my_list[i], &pset.popt);
2727
2728 printf("%-24s %s\n", my_list[i], val);
2729 free(val);
2730 }
2731
2732 success = true;
2733 }
2734 else
2736
2737 free(opt0);
2738 free(opt1);
2739 }
2740 else
2742
2744}
2745
2746/*
2747 * \q or \quit -- exit psql
2748 */
2749static backslashResult
2751{
2753
2754 if (active_branch)
2755 status = PSQL_CMD_TERMINATE;
2756
2757 return status;
2758}
2759
2760/*
2761 * \r -- reset (clear) the query buffer
2762 */
2763static backslashResult
2766{
2767 if (active_branch)
2768 {
2771 if (!pset.quiet)
2772 puts(_("Query buffer reset (cleared)."));
2773 }
2774
2775 return PSQL_CMD_SKIP_LINE;
2776}
2777
2778/*
2779 * \restrict -- enter "restricted mode" with the provided key
2780 */
2781static backslashResult
2783 const char *cmd)
2784{
2785 if (active_branch)
2786 {
2787 char *opt;
2788
2790
2792 if (opt == NULL || opt[0] == '\0')
2793 {
2794 pg_log_error("\\%s: missing required argument", cmd);
2795 return PSQL_CMD_ERROR;
2796 }
2797
2798 restrict_key = pstrdup(opt);
2799 restricted = true;
2800 }
2801 else
2803
2804 return PSQL_CMD_SKIP_LINE;
2805}
2806
2807/*
2808 * \s -- save history in a file or show it on the screen
2809 */
2810static backslashResult
2812{
2813 bool success = true;
2814
2815 if (active_branch)
2816 {
2817 char *fname = psql_scan_slash_option(scan_state,
2818 OT_NORMAL, NULL, true);
2819
2820 expand_tilde(&fname);
2822 if (success && !pset.quiet && fname)
2823 printf(_("Wrote history to file \"%s\".\n"), fname);
2824 if (!fname)
2825 putchar('\n');
2826 free(fname);
2827 }
2828 else
2830
2832}
2833
2834/*
2835 * \sendpipeline -- send an extended query to an ongoing pipeline
2836 */
2837static backslashResult
2839{
2841
2842 if (active_branch)
2843 {
2845 {
2848 {
2849 status = PSQL_CMD_SEND;
2850 }
2851 else
2852 {
2853 pg_log_error("\\sendpipeline must be used after \\bind or \\bind_named");
2855 return PSQL_CMD_ERROR;
2856 }
2857 }
2858 else
2859 {
2860 pg_log_error("\\sendpipeline not allowed outside of pipeline mode");
2862 return PSQL_CMD_ERROR;
2863 }
2864 }
2865 else
2867
2868 return status;
2869}
2870
2871/*
2872 * \set -- set variable
2873 */
2874static backslashResult
2876{
2877 bool success = true;
2878
2879 if (active_branch)
2880 {
2882 OT_NORMAL, NULL, false);
2883
2884 if (!opt0)
2885 {
2886 /* list all variables */
2888 success = true;
2889 }
2890 else
2891 {
2892 /*
2893 * Set variable to the concatenation of the arguments.
2894 */
2895 char *newval;
2896 char *opt;
2897
2899 OT_NORMAL, NULL, false);
2900 newval = pg_strdup(opt ? opt : "");
2901 free(opt);
2902
2903 while ((opt = psql_scan_slash_option(scan_state,
2904 OT_NORMAL, NULL, false)))
2905 {
2906 newval = pg_realloc(newval, strlen(newval) + strlen(opt) + 1);
2907 strcat(newval, opt);
2908 free(opt);
2909 }
2910
2912 success = false;
2913
2914 pg_free(newval);
2915 }
2916 free(opt0);
2917 }
2918 else
2920
2922}
2923
2924/*
2925 * \setenv -- set environment variable
2926 */
2927static backslashResult
2929 const char *cmd)
2930{
2931 bool success = true;
2932
2933 if (active_branch)
2934 {
2935 char *envvar = psql_scan_slash_option(scan_state,
2936 OT_NORMAL, NULL, false);
2938 OT_NORMAL, NULL, false);
2939
2940 if (!envvar)
2941 {
2942 pg_log_error("\\%s: missing required argument", cmd);
2943 success = false;
2944 }
2945 else if (strchr(envvar, '=') != NULL)
2946 {
2947 pg_log_error("\\%s: environment variable name must not contain \"=\"",
2948 cmd);
2949 success = false;
2950 }
2951 else if (!envval)
2952 {
2953 /* No argument - unset the environment variable */
2954 unsetenv(envvar);
2955 success = true;
2956 }
2957 else
2958 {
2959 /* Set variable to the value of the next argument */
2960 setenv(envvar, envval, 1);
2961 success = true;
2962 }
2963 free(envvar);
2964 free(envval);
2965 }
2966 else
2968
2970}
2971
2972/*
2973 * \sf/\sv -- show a function/view's source code
2974 */
2975static backslashResult
2977 const char *cmd, bool is_func)
2978{
2980
2981 if (active_branch)
2982 {
2983 bool show_linenumbers = (strchr(cmd, '+') != NULL);
2985 char *obj_desc;
2988
2991 OT_WHOLE_LINE, NULL, true);
2992 if (!obj_desc)
2993 {
2994 if (is_func)
2995 pg_log_error("function name is required");
2996 else
2997 pg_log_error("view name is required");
2998 status = PSQL_CMD_ERROR;
2999 }
3000 else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
3001 {
3002 /* error already reported */
3003 status = PSQL_CMD_ERROR;
3004 }
3005 else if (!get_create_object_cmd(eot, obj_oid, buf))
3006 {
3007 /* error already reported */
3008 status = PSQL_CMD_ERROR;
3009 }
3010 else
3011 {
3012 FILE *output;
3013 bool is_pager;
3014
3015 /* Select output stream: stdout, pager, or file */
3016 if (pset.queryFout == stdout)
3017 {
3018 /* count lines in function to see if pager is needed */
3019 int lineno = count_lines_in_buf(buf);
3020
3021 output = PageOutput(lineno, &(pset.popt.topt));
3022 is_pager = true;
3023 }
3024 else
3025 {
3026 /* use previously set output file, without pager */
3028 is_pager = false;
3029 }
3030
3031 if (show_linenumbers)
3032 {
3033 /* add line numbers */
3034 print_with_linenumbers(output, buf->data, is_func);
3035 }
3036 else
3037 {
3038 /* just send the definition to output */
3039 fputs(buf->data, output);
3040 }
3041
3042 if (is_pager)
3044 }
3045
3046 free(obj_desc);
3048 }
3049 else
3051
3052 return status;
3053}
3054
3055/*
3056 * \startpipeline -- enter pipeline mode
3057 */
3058static backslashResult
3060{
3062
3063 if (active_branch)
3064 {
3066 status = PSQL_CMD_SEND;
3067 }
3068 else
3070
3071 return status;
3072}
3073
3074/*
3075 * \syncpipeline -- send a sync message to an active pipeline
3076 */
3077static backslashResult
3079{
3081
3082 if (active_branch)
3083 {
3085 status = PSQL_CMD_SEND;
3086 }
3087 else
3089
3090 return status;
3091}
3092
3093/*
3094 * \endpipeline -- end pipeline mode
3095 */
3096static backslashResult
3098{
3100
3101 if (active_branch)
3102 {
3104 status = PSQL_CMD_SEND;
3105 }
3106 else
3108
3109 return status;
3110}
3111
3112/*
3113 * \t -- turn off table headers and row count
3114 */
3115static backslashResult
3117{
3118 bool success = true;
3119
3120 if (active_branch)
3121 {
3123 OT_NORMAL, NULL, true);
3124
3125 success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
3126 free(opt);
3127 }
3128 else
3130
3132}
3133
3134/*
3135 * \T -- define html <table ...> attributes
3136 */
3137static backslashResult
3139{
3140 bool success = true;
3141
3142 if (active_branch)
3143 {
3145 OT_NORMAL, NULL, false);
3146
3147 success = do_pset("tableattr", value, &pset.popt, pset.quiet);
3148 free(value);
3149 }
3150 else
3152
3154}
3155
3156/*
3157 * \timing -- enable/disable timing of queries
3158 */
3159static backslashResult
3161{
3162 bool success = true;
3163
3164 if (active_branch)
3165 {
3167 OT_NORMAL, NULL, false);
3168
3169 if (opt)
3170 success = ParseVariableBool(opt, "\\timing", &pset.timing);
3171 else
3173 if (!pset.quiet)
3174 {
3175 if (pset.timing)
3176 puts(_("Timing is on."));
3177 else
3178 puts(_("Timing is off."));
3179 }
3180 free(opt);
3181 }
3182 else
3184
3186}
3187
3188/*
3189 * \unrestrict -- exit "restricted mode" if provided key matches
3190 */
3191static backslashResult
3193 const char *cmd)
3194{
3195 if (active_branch)
3196 {
3197 char *opt;
3198
3200 if (opt == NULL || opt[0] == '\0')
3201 {
3202 pg_log_error("\\%s: missing required argument", cmd);
3203 return PSQL_CMD_ERROR;
3204 }
3205
3206 if (!restricted)
3207 {
3208 pg_log_error("\\%s: not currently in restricted mode", cmd);
3209 return PSQL_CMD_ERROR;
3210 }
3211 else if (strcmp(opt, restrict_key) == 0)
3212 {
3214 restricted = false;
3215 }
3216 else
3217 {
3218 pg_log_error("\\%s: wrong key", cmd);
3219 return PSQL_CMD_ERROR;
3220 }
3221 }
3222 else
3224
3225 return PSQL_CMD_SKIP_LINE;
3226}
3227
3228/*
3229 * \unset -- unset variable
3230 */
3231static backslashResult
3233 const char *cmd)
3234{
3235 bool success = true;
3236
3237 if (active_branch)
3238 {
3240 OT_NORMAL, NULL, false);
3241
3242 if (!opt)
3243 {
3244 pg_log_error("\\%s: missing required argument", cmd);
3245 success = false;
3246 }
3247 else if (!SetVariable(pset.vars, opt, NULL))
3248 success = false;
3249
3250 free(opt);
3251 }
3252 else
3254
3256}
3257
3258/*
3259 * \w -- write query buffer to file
3260 */
3261static backslashResult
3263 const char *cmd,
3265{
3267
3268 if (active_branch)
3269 {
3270 char *fname = psql_scan_slash_option(scan_state,
3271 OT_FILEPIPE, NULL, true);
3272 FILE *fd = NULL;
3273 bool is_pipe = false;
3274
3275 if (!query_buf)
3276 {
3277 pg_log_error("no query buffer");
3278 status = PSQL_CMD_ERROR;
3279 }
3280 else
3281 {
3282 if (!fname)
3283 {
3284 pg_log_error("\\%s: missing required argument", cmd);
3285 status = PSQL_CMD_ERROR;
3286 }
3287 else
3288 {
3289 expand_tilde(&fname);
3290 if (fname[0] == '|')
3291 {
3292 is_pipe = true;
3293 fflush(NULL);
3295 fd = popen(&fname[1], "w");
3296 }
3297 else
3298 {
3300 fd = fopen(fname, "w");
3301 }
3302 if (!fd)
3303 {
3304 pg_log_error("%s: %m", fname);
3305 status = PSQL_CMD_ERROR;
3306 }
3307 }
3308 }
3309
3310 if (fd)
3311 {
3312 int result;
3313
3314 /*
3315 * We want to print the same thing \g would execute, but not to
3316 * change the query buffer state; so we can't use
3317 * copy_previous_query(). Also, beware of possibility that buffer
3318 * pointers are NULL.
3319 */
3320 if (query_buf && query_buf->len > 0)
3321 fprintf(fd, "%s\n", query_buf->data);
3322 else if (previous_buf && previous_buf->len > 0)
3323 fprintf(fd, "%s\n", previous_buf->data);
3324
3325 if (is_pipe)
3326 {
3327 result = pclose(fd);
3328
3329 if (result != 0)
3330 {
3331 pg_log_error("%s: %s", fname, wait_result_to_str(result));
3332 status = PSQL_CMD_ERROR;
3333 }
3335 }
3336 else
3337 {
3338 result = fclose(fd);
3339
3340 if (result == EOF)
3341 {
3342 pg_log_error("%s: %m", fname);
3343 status = PSQL_CMD_ERROR;
3344 }
3345 }
3346 }
3347
3348 if (is_pipe)
3350
3351 free(fname);
3352 }
3353 else
3355
3356 return status;
3357}
3358
3359/*
3360 * \watch -- execute a query every N seconds.
3361 * Optionally, stop after M iterations.
3362 */
3363static backslashResult
3366{
3367 bool success = true;
3368
3369 if (active_branch)
3370 {
3371 bool have_sleep = false;
3372 bool have_iter = false;
3373 bool have_min_rows = false;
3374 double sleep = pset.watch_interval;
3375 int iter = 0;
3376 int min_rows = 0;
3377
3379 {
3380 pg_log_error("\\%s not allowed in pipeline mode", "watch");
3382 success = false;
3383 }
3384
3385 /*
3386 * Parse arguments. We allow either an unlabeled interval or
3387 * "name=value", where name is from the set ('i', 'interval', 'c',
3388 * 'count', 'm', 'min_rows'). The parsing of interval value should be
3389 * kept in sync with ParseVariableDouble which is used for setting the
3390 * default interval value.
3391 */
3392 while (success)
3393 {
3395 OT_NORMAL, NULL, true);
3396 char *valptr;
3397 char *opt_end;
3398
3399 if (!opt)
3400 break; /* no more arguments */
3401
3402 valptr = strchr(opt, '=');
3403 if (valptr)
3404 {
3405 /* Labeled argument */
3406 valptr++;
3407 if (strncmp("i=", opt, strlen("i=")) == 0 ||
3408 strncmp("interval=", opt, strlen("interval=")) == 0)
3409 {
3410 if (have_sleep)
3411 {
3412 pg_log_error("\\watch: interval value is specified more than once");
3413 success = false;
3414 }
3415 else
3416 {
3417 have_sleep = true;
3418 errno = 0;
3420 if (sleep < 0 || *opt_end || errno == ERANGE)
3421 {
3422 pg_log_error("\\watch: incorrect interval value \"%s\"", valptr);
3423 success = false;
3424 }
3425 }
3426 }
3427 else if (strncmp("c=", opt, strlen("c=")) == 0 ||
3428 strncmp("count=", opt, strlen("count=")) == 0)
3429 {
3430 if (have_iter)
3431 {
3432 pg_log_error("\\watch: iteration count is specified more than once");
3433 success = false;
3434 }
3435 else
3436 {
3437 have_iter = true;
3438 errno = 0;
3439 iter = strtoint(valptr, &opt_end, 10);
3440 if (iter <= 0 || *opt_end || errno == ERANGE)
3441 {
3442 pg_log_error("\\watch: incorrect iteration count \"%s\"", valptr);
3443 success = false;
3444 }
3445 }
3446 }
3447 else if (strncmp("m=", opt, strlen("m=")) == 0 ||
3448 strncmp("min_rows=", opt, strlen("min_rows=")) == 0)
3449 {
3450 if (have_min_rows)
3451 {
3452 pg_log_error("\\watch: minimum row count specified more than once");
3453 success = false;
3454 }
3455 else
3456 {
3457 have_min_rows = true;
3458 errno = 0;
3460 if (min_rows <= 0 || *opt_end || errno == ERANGE)
3461 {
3462 pg_log_error("\\watch: incorrect minimum row count \"%s\"", valptr);
3463 success = false;
3464 }
3465 }
3466 }
3467 else
3468 {
3469 pg_log_error("\\watch: unrecognized parameter \"%s\"", opt);
3470 success = false;
3471 }
3472 }
3473 else
3474 {
3475 /* Unlabeled argument: take it as interval */
3476 if (have_sleep)
3477 {
3478 pg_log_error("\\watch: interval value is specified more than once");
3479 success = false;
3480 }
3481 else
3482 {
3483 have_sleep = true;
3484 errno = 0;
3485 sleep = strtod(opt, &opt_end);
3486 if (sleep < 0 || *opt_end || errno == ERANGE)
3487 {
3488 pg_log_error("\\watch: incorrect interval value \"%s\"", opt);
3489 success = false;
3490 }
3491 }
3492 }
3493
3494 free(opt);
3495 }
3496
3497 /* If we parsed arguments successfully, do the command */
3498 if (success)
3499 {
3500 /* If query_buf is empty, recall and execute previous query */
3502
3504 }
3505
3506 /* Reset the query buffer as though for \r */
3509 }
3510 else
3512
3514}
3515
3516/*
3517 * \x -- set or toggle expanded table representation
3518 */
3519static backslashResult
3521{
3522 bool success = true;
3523
3524 if (active_branch)
3525 {
3527 OT_NORMAL, NULL, true);
3528
3529 success = do_pset("expanded", opt, &pset.popt, pset.quiet);
3530 free(opt);
3531 }
3532 else
3534
3536}
3537
3538/*
3539 * \z -- list table privileges (equivalent to \dp)
3540 */
3541static backslashResult
3543{
3544 bool success = true;
3545
3546 if (active_branch)
3547 {
3548 char *pattern;
3549 bool show_system;
3550 unsigned short int save_expanded;
3551
3553 OT_NORMAL, NULL, true);
3554
3555 show_system = strchr(cmd, 'S') ? true : false;
3556
3557 /* if 'x' option specified, force expanded mode */
3559 if (strchr(cmd, 'x'))
3560 pset.popt.topt.expanded = 1;
3561
3563
3564 /* restore original expanded mode */
3566
3567 free(pattern);
3568 }
3569 else
3571
3573}
3574
3575/*
3576 * \! -- execute shell command
3577 */
3578static backslashResult
3580{
3581 bool success = true;
3582
3583 if (active_branch)
3584 {
3586 OT_WHOLE_LINE, NULL, false);
3587
3588 success = do_shell(opt);
3589 free(opt);
3590 }
3591 else
3593
3595}
3596
3597/*
3598 * \? -- print help about backslash commands
3599 */
3600static backslashResult
3602{
3603 if (active_branch)
3604 {
3606 OT_NORMAL, NULL, false);
3607
3608 if (!opt0 || strcmp(opt0, "commands") == 0)
3610 else if (strcmp(opt0, "options") == 0)
3612 else if (strcmp(opt0, "variables") == 0)
3614 else
3616
3617 free(opt0);
3618 }
3619 else
3621
3622 return PSQL_CMD_SKIP_LINE;
3623}
3624
3625
3626/*
3627 * Read and interpret an argument to the \connect slash command.
3628 *
3629 * Returns a malloc'd string, or NULL if no/empty argument.
3630 */
3631static char *
3633{
3634 char *result;
3635 char quote;
3636
3637 /*
3638 * Ideally we should treat the arguments as SQL identifiers. But for
3639 * backwards compatibility with 7.2 and older pg_dump files, we have to
3640 * take unquoted arguments verbatim (don't downcase them). For now,
3641 * double-quoted arguments may be stripped of double quotes (as if SQL
3642 * identifiers). By 7.4 or so, pg_dump files can be expected to
3643 * double-quote all mixed-case \connect arguments, and then we can get rid
3644 * of OT_SQLIDHACK.
3645 */
3647
3648 if (!result)
3649 return NULL;
3650
3651 if (quote)
3652 return result;
3653
3654 if (*result == '\0' || strcmp(result, "-") == 0)
3655 {
3656 free(result);
3657 return NULL;
3658 }
3659
3660 return result;
3661}
3662
3663/*
3664 * Read a boolean expression, return it as a PQExpBuffer string.
3665 *
3666 * Note: anything more or less than one token will certainly fail to be
3667 * parsed by ParseVariableBool, so we don't worry about complaining here.
3668 * This routine's return data structure will need to be rethought anyway
3669 * to support likely future extensions such as "\if defined VARNAME".
3670 */
3671static PQExpBuffer
3673{
3675 int num_options = 0;
3676 char *value;
3677
3678 /* collect all arguments for the conditional command into exp_buf */
3680 OT_NORMAL, NULL, false)) != NULL)
3681 {
3682 /* add spaces between tokens */
3683 if (num_options > 0)
3686 num_options++;
3687 free(value);
3688 }
3689
3690 return exp_buf;
3691}
3692
3693/*
3694 * Read a boolean expression, return true if the expression
3695 * was a valid boolean expression that evaluated to true.
3696 * Otherwise return false.
3697 *
3698 * Note: conditional stack's top state must be active, else lexer will
3699 * fail to expand variables and backticks.
3700 */
3701static bool
3703{
3705 bool value = false;
3706 bool success = ParseVariableBool(buf->data, name, &value);
3707
3709 return success && value;
3710}
3711
3712/*
3713 * Read a boolean expression, but do nothing with it.
3714 *
3715 * Note: conditional stack's top state must be INACTIVE, else lexer will
3716 * expand variables and backticks, which we do not want here.
3717 */
3718static void
3725
3726/*
3727 * Read and discard "normal" slash command options.
3728 *
3729 * This should be used for inactive-branch processing of any slash command
3730 * that eats one or more OT_NORMAL, OT_SQLID, or OT_SQLIDHACK parameters.
3731 * We don't need to worry about exactly how many it would eat, since the
3732 * cleanup logic in HandleSlashCmds would silently discard any extras anyway.
3733 */
3734static void
3736{
3737 char *arg;
3738
3740 OT_NORMAL, NULL, false)) != NULL)
3741 free(arg);
3742}
3743
3744/*
3745 * Read and discard FILEPIPE slash command argument.
3746 *
3747 * This *MUST* be used for inactive-branch processing of any slash command
3748 * that takes an OT_FILEPIPE option. Otherwise we might consume a different
3749 * amount of option text in active and inactive cases.
3750 */
3751static void
3759
3760/*
3761 * Read and discard whole-line slash command argument.
3762 *
3763 * This *MUST* be used for inactive-branch processing of any slash command
3764 * that takes an OT_WHOLE_LINE option. Otherwise we might consume a different
3765 * amount of option text in active and inactive cases.
3766 *
3767 * Note: although callers might pass "semicolon" as either true or false,
3768 * we need not duplicate that here, since it doesn't affect the amount of
3769 * input text consumed.
3770 */
3771static void
3779
3780/*
3781 * Return true if the command given is a branching command.
3782 */
3783static bool
3784is_branching_command(const char *cmd)
3785{
3786 return (strcmp(cmd, "if") == 0 ||
3787 strcmp(cmd, "elif") == 0 ||
3788 strcmp(cmd, "else") == 0 ||
3789 strcmp(cmd, "endif") == 0);
3790}
3791
3792/*
3793 * Prepare to possibly restore query buffer to its current state
3794 * (cf. discard_query_text).
3795 *
3796 * We need to remember the length of the query buffer, and the lexer's
3797 * notion of the parenthesis nesting depth.
3798 */
3799static void
3808
3809/*
3810 * Discard any query text absorbed during an inactive conditional branch.
3811 *
3812 * We must discard data that was appended to query_buf during an inactive
3813 * \if branch. We don't have to do anything there if there's no query_buf.
3814 *
3815 * Also, reset the lexer state to the same paren depth there was before.
3816 * (The rest of its state doesn't need attention, since we could not be
3817 * inside a comment or literal or partial token.)
3818 */
3819static void
3834
3835/*
3836 * If query_buf is empty, copy previous_buf into it.
3837 *
3838 * This is used by various slash commands for which re-execution of a
3839 * previous query is a common usage. For convenience, we allow the
3840 * case of query_buf == NULL (and do nothing).
3841 *
3842 * Returns "true" if the previous query was copied into the query
3843 * buffer, else "false".
3844 */
3845static bool
3847{
3848 if (query_buf && query_buf->len == 0)
3849 {
3851 return true;
3852 }
3853 return false;
3854}
3855
3856/*
3857 * Ask the user for a password; 'username' is the username the
3858 * password is for, if one has been explicitly specified.
3859 * Returns a malloc'd string.
3860 * If 'canceled' is provided, *canceled will be set to true if the prompt
3861 * is canceled via SIGINT, and to false otherwise.
3862 */
3863static char *
3864prompt_for_password(const char *username, bool *canceled)
3865{
3866 char *result;
3868
3869 /* Set up to let SIGINT cancel simple_prompt_extended() */
3872 prompt_ctx.canceled = false;
3873
3874 if (username == NULL || username[0] == '\0')
3875 result = simple_prompt_extended("Password: ", false, &prompt_ctx);
3876 else
3877 {
3878 char *prompt_text;
3879
3880 prompt_text = psprintf(_("Password for user %s: "), username);
3883 }
3884
3885 if (canceled)
3886 *canceled = prompt_ctx.canceled;
3887
3888 return result;
3889}
3890
3891static bool
3892param_is_newly_set(const char *old_val, const char *new_val)
3893{
3894 if (new_val == NULL)
3895 return false;
3896
3897 if (old_val == NULL || strcmp(old_val, new_val) != 0)
3898 return true;
3899
3900 return false;
3901}
3902
3903/*
3904 * do_connect -- handler for \connect
3905 *
3906 * Connects to a database with given parameters. If we are told to re-use
3907 * parameters, parameters from the previous connection are used where the
3908 * command's own options do not supply a value. Otherwise, libpq defaults
3909 * are used.
3910 *
3911 * In interactive mode, if connection fails with the given parameters,
3912 * the old connection will be kept.
3913 */
3914static bool
3916 char *dbname, char *user, char *host, char *port)
3917{
3918 PGconn *o_conn = pset.db,
3919 *n_conn = NULL;
3921 int nconnopts = 0;
3922 bool same_host = false;
3923 char *password = NULL;
3924 char *client_encoding;
3925 bool success = true;
3926 bool keep_password = true;
3928 bool reuse_previous;
3929
3932
3933 /* Complain if we have additional arguments after a connection string. */
3934 if (has_connection_string && (user || host || port))
3935 {
3936 pg_log_error("Do not give user, host, or port separately when using a connection string");
3937 return false;
3938 }
3939
3941 {
3942 case TRI_YES:
3943 reuse_previous = true;
3944 break;
3945 case TRI_NO:
3946 reuse_previous = false;
3947 break;
3948 default:
3950 break;
3951 }
3952
3953 /*
3954 * If we intend to re-use connection parameters, collect them out of the
3955 * old connection, then replace individual values as necessary. (We may
3956 * need to resort to looking at pset.dead_conn, if the connection died
3957 * previously.) Otherwise, obtain a PQconninfoOption array containing
3958 * libpq's defaults, and modify that. Note this function assumes that
3959 * PQconninfo, PQconndefaults, and PQconninfoParse will all produce arrays
3960 * containing the same options in the same order.
3961 */
3962 if (reuse_previous)
3963 {
3964 if (o_conn)
3966 else if (pset.dead_conn)
3968 else
3969 {
3970 /* This is reachable after a non-interactive \connect failure */
3971 pg_log_error("No database connection exists to re-use parameters from");
3972 return false;
3973 }
3974 }
3975 else
3977
3978 if (cinfo)
3979 {
3981 {
3982 /* Parse the connstring and insert values into cinfo */
3984 char *errmsg;
3985
3987 if (replcinfo)
3988 {
3991 bool have_password = false;
3992
3993 for (ci = cinfo, replci = replcinfo;
3994 ci->keyword && replci->keyword;
3995 ci++, replci++)
3996 {
3997 Assert(strcmp(ci->keyword, replci->keyword) == 0);
3998 /* Insert value from connstring if one was provided */
3999 if (replci->val)
4000 {
4001 /*
4002 * We know that both val strings were allocated by
4003 * libpq, so the least messy way to avoid memory leaks
4004 * is to swap them.
4005 */
4006 char *swap = replci->val;
4007
4008 replci->val = ci->val;
4009 ci->val = swap;
4010
4011 /*
4012 * Check whether connstring provides options affecting
4013 * password re-use. While any change in user, host,
4014 * hostaddr, or port causes us to ignore the old
4015 * connection's password, we don't force that for
4016 * dbname, since passwords aren't database-specific.
4017 */
4018 if (replci->val == NULL ||
4019 strcmp(ci->val, replci->val) != 0)
4020 {
4021 if (strcmp(replci->keyword, "user") == 0 ||
4022 strcmp(replci->keyword, "host") == 0 ||
4023 strcmp(replci->keyword, "hostaddr") == 0 ||
4024 strcmp(replci->keyword, "port") == 0)
4025 keep_password = false;
4026 }
4027 /* Also note whether connstring contains a password. */
4028 if (strcmp(replci->keyword, "password") == 0)
4029 have_password = true;
4030 }
4031 else if (!reuse_previous)
4032 {
4033 /*
4034 * When we have a connstring and are not re-using
4035 * parameters, swap *all* entries, even those not set
4036 * by the connstring. This avoids absorbing
4037 * environment-dependent defaults from the result of
4038 * PQconndefaults(). We don't want to do that because
4039 * they'd override service-file entries if the
4040 * connstring specifies a service parameter, whereas
4041 * the priority should be the other way around. libpq
4042 * can certainly recompute any defaults we don't pass
4043 * here. (In this situation, it's a bit wasteful to
4044 * have called PQconndefaults() at all, but not doing
4045 * so would require yet another major code path here.)
4046 */
4047 replci->val = ci->val;
4048 ci->val = NULL;
4049 }
4050 }
4051 Assert(ci->keyword == NULL && replci->keyword == NULL);
4052
4053 /* While here, determine how many option slots there are */
4054 nconnopts = ci - cinfo;
4055
4057
4058 /*
4059 * If the connstring contains a password, tell the loop below
4060 * that we may use it, regardless of other settings (i.e.,
4061 * cinfo's password is no longer an "old" password).
4062 */
4063 if (have_password)
4064 keep_password = true;
4065
4066 /* Don't let code below try to inject dbname into params. */
4067 dbname = NULL;
4068 }
4069 else
4070 {
4071 /* PQconninfoParse failed */
4072 if (errmsg)
4073 {
4074 pg_log_error("%s", errmsg);
4076 }
4077 else
4078 pg_log_error("out of memory");
4079 success = false;
4080 }
4081 }
4082 else
4083 {
4084 /*
4085 * If dbname isn't a connection string, then we'll inject it and
4086 * the other parameters into the keyword array below. (We can't
4087 * easily insert them into the cinfo array because of memory
4088 * management issues: PQconninfoFree would misbehave on Windows.)
4089 * However, to avoid dependencies on the order in which parameters
4090 * appear in the array, make a preliminary scan to set
4091 * keep_password and same_host correctly.
4092 *
4093 * While any change in user, host, or port causes us to ignore the
4094 * old connection's password, we don't force that for dbname,
4095 * since passwords aren't database-specific.
4096 */
4098
4099 for (ci = cinfo; ci->keyword; ci++)
4100 {
4101 if (user && strcmp(ci->keyword, "user") == 0)
4102 {
4103 if (!(ci->val && strcmp(user, ci->val) == 0))
4104 keep_password = false;
4105 }
4106 else if (host && strcmp(ci->keyword, "host") == 0)
4107 {
4108 if (ci->val && strcmp(host, ci->val) == 0)
4109 same_host = true;
4110 else
4111 keep_password = false;
4112 }
4113 else if (port && strcmp(ci->keyword, "port") == 0)
4114 {
4115 if (!(ci->val && strcmp(port, ci->val) == 0))
4116 keep_password = false;
4117 }
4118 }
4119
4120 /* While here, determine how many option slots there are */
4121 nconnopts = ci - cinfo;
4122 }
4123 }
4124 else
4125 {
4126 /* We failed to create the cinfo structure */
4127 pg_log_error("out of memory");
4128 success = false;
4129 }
4130
4131 /*
4132 * If the user asked to be prompted for a password, ask for one now. If
4133 * not, use the password from the old connection, provided the username
4134 * etc have not changed. Otherwise, try to connect without a password
4135 * first, and then ask for a password if needed.
4136 *
4137 * XXX: this behavior leads to spurious connection attempts recorded in
4138 * the postmaster's log. But libpq offers no API that would let us obtain
4139 * a password and then continue with the first connection attempt.
4140 */
4141 if (pset.getPassword == TRI_YES && success)
4142 {
4143 bool canceled = false;
4144
4145 /*
4146 * If a connstring or URI is provided, we don't know which username
4147 * will be used, since we haven't dug that out of the connstring.
4148 * Don't risk issuing a misleading prompt. As in startup.c, it does
4149 * not seem worth working harder, since this getPassword setting is
4150 * normally only used in noninteractive cases.
4151 */
4153 &canceled);
4154 success = !canceled;
4155 }
4156
4157 /*
4158 * Consider whether to force client_encoding to "auto" (overriding
4159 * anything in the connection string). We do so if we have a terminal
4160 * connection and there is no PGCLIENTENCODING environment setting.
4161 */
4162 if (pset.notty || getenv("PGCLIENTENCODING"))
4163 client_encoding = NULL;
4164 else
4165 client_encoding = "auto";
4166
4167 /* Loop till we have a connection or fail, which we might've already */
4168 while (success)
4169 {
4170 const char **keywords = pg_malloc_array(const char *, nconnopts + 1);
4171 const char **values = pg_malloc_array(const char *, nconnopts + 1);
4172 int paramnum = 0;
4174
4175 /*
4176 * Copy non-default settings into the PQconnectdbParams parameter
4177 * arrays; but inject any values specified old-style, as well as any
4178 * interactively-obtained password, and a couple of fields we want to
4179 * set forcibly.
4180 *
4181 * If you change this code, see also the initial-connection code in
4182 * main().
4183 */
4184 for (ci = cinfo; ci->keyword; ci++)
4185 {
4187
4188 if (dbname && strcmp(ci->keyword, "dbname") == 0)
4189 values[paramnum++] = dbname;
4190 else if (user && strcmp(ci->keyword, "user") == 0)
4191 values[paramnum++] = user;
4192 else if (host && strcmp(ci->keyword, "host") == 0)
4193 values[paramnum++] = host;
4194 else if (host && !same_host && strcmp(ci->keyword, "hostaddr") == 0)
4195 {
4196 /* If we're changing the host value, drop any old hostaddr */
4197 values[paramnum++] = NULL;
4198 }
4199 else if (port && strcmp(ci->keyword, "port") == 0)
4200 values[paramnum++] = port;
4201 /* If !keep_password, we unconditionally drop old password */
4202 else if ((password || !keep_password) &&
4203 strcmp(ci->keyword, "password") == 0)
4205 else if (strcmp(ci->keyword, "fallback_application_name") == 0)
4207 else if (client_encoding &&
4208 strcmp(ci->keyword, "client_encoding") == 0)
4209 values[paramnum++] = client_encoding;
4210 else if (ci->val)
4211 values[paramnum++] = ci->val;
4212 /* else, don't bother making libpq parse this keyword */
4213 }
4214 /* add array terminator */
4216 values[paramnum] = NULL;
4217
4218 /* Note we do not want libpq to re-expand the dbname parameter */
4220
4222 pg_free(values);
4223
4226 break;
4227
4228 /*
4229 * Connection attempt failed; either retry the connection attempt with
4230 * a new password, or give up.
4231 */
4233 {
4234 bool canceled = false;
4235
4236 /*
4237 * Prompt for password using the username we actually connected
4238 * with --- it might've come out of "dbname" rather than "user".
4239 */
4242 n_conn = NULL;
4243 success = !canceled;
4244 continue;
4245 }
4246
4247 /*
4248 * We'll report the error below ... unless n_conn is NULL, indicating
4249 * that libpq didn't have enough memory to make a PGconn.
4250 */
4251 if (n_conn == NULL)
4252 pg_log_error("out of memory");
4253
4254 success = false;
4255 } /* end retry loop */
4256
4257 /* Release locally allocated data, whether we succeeded or not */
4260
4261 if (!success)
4262 {
4263 /*
4264 * Failed to connect to the database. In interactive mode, keep the
4265 * previous connection to the DB; in scripting mode, close our
4266 * previous connection as well.
4267 */
4269 {
4270 if (n_conn)
4271 {
4274 }
4275
4276 /* pset.db is left unmodified */
4277 if (o_conn)
4278 pg_log_info("Previous connection kept");
4279 }
4280 else
4281 {
4282 if (n_conn)
4283 {
4284 pg_log_error("\\connect: %s", PQerrorMessage(n_conn));
4286 }
4287
4288 if (o_conn)
4289 {
4290 /*
4291 * Transition to having no connection.
4292 *
4293 * Unlike CheckConnection(), we close the old connection
4294 * immediately to prevent its parameters from being re-used.
4295 * This is so that a script cannot accidentally reuse
4296 * parameters it did not expect to. Otherwise, the state
4297 * cleanup should be the same as in CheckConnection().
4298 */
4300 pset.db = NULL;
4303 }
4304
4305 /* On the same reasoning, release any dead_conn to prevent reuse */
4306 if (pset.dead_conn)
4307 {
4310 }
4311 }
4312
4313 return false;
4314 }
4315
4316 /*
4317 * Replace the old connection with the new one, and update
4318 * connection-dependent variables. Keep the resynchronization logic in
4319 * sync with CheckConnection().
4320 */
4322 pset.db = n_conn;
4323 SyncVariables();
4324 connection_warnings(false); /* Must be after SyncVariables */
4325
4326 /* Tell the user about the new connection */
4327 if (!pset.quiet)
4328 {
4329 if (!o_conn ||
4332 {
4333 char *connhost = PQhost(pset.db);
4334 char *hostaddr = PQhostaddr(pset.db);
4335
4336 if (is_unixsock_path(connhost))
4337 {
4338 /* hostaddr overrides connhost */
4339 if (hostaddr && *hostaddr)
4340 printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
4341 PQdb(pset.db), PQuser(pset.db), hostaddr, PQport(pset.db));
4342 else
4343 printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
4344 PQdb(pset.db), PQuser(pset.db), connhost, PQport(pset.db));
4345 }
4346 else
4347 {
4348 if (hostaddr && *hostaddr && strcmp(connhost, hostaddr) != 0)
4349 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
4350 PQdb(pset.db), PQuser(pset.db), connhost, hostaddr, PQport(pset.db));
4351 else
4352 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
4353 PQdb(pset.db), PQuser(pset.db), connhost, PQport(pset.db));
4354 }
4355 }
4356 else
4357 printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
4358 PQdb(pset.db), PQuser(pset.db));
4359 }
4360
4361 /* Drop no-longer-needed connection(s) */
4362 if (o_conn)
4364 if (pset.dead_conn)
4365 {
4368 }
4369
4370 return true;
4371}
4372
4373/*
4374 * Processes the connection sequence described by PQconnectStartParams(). Don't
4375 * worry about reporting errors in this function. Our caller will check the
4376 * connection's status, and report appropriately.
4377 */
4378static void
4380{
4381 bool forRead = false;
4382
4383 while (true)
4384 {
4385 int rc;
4386 int sock;
4388
4389 /*
4390 * On every iteration of the connection sequence, let's check if the
4391 * user has requested a cancellation.
4392 */
4393 if (cancel_pressed)
4394 break;
4395
4396 /*
4397 * Do not assume that the socket remains the same across
4398 * PQconnectPoll() calls.
4399 */
4400 sock = PQsocket(conn);
4401 if (sock == -1)
4402 break;
4403
4404 /*
4405 * If the user sends SIGINT between the cancel_pressed check, and
4406 * polling of the socket, it will not be recognized. Instead, we will
4407 * just wait until the next step in the connection sequence or
4408 * forever, which might require users to send SIGTERM or SIGQUIT.
4409 *
4410 * Some solutions would include the "self-pipe trick," using
4411 * pselect(2) and ppoll(2), or using a timeout.
4412 *
4413 * The self-pipe trick requires a bit of code to setup. pselect(2) and
4414 * ppoll(2) are not on all the platforms we support. The simplest
4415 * solution happens to just be adding a timeout, so let's wait for 1
4416 * second and check cancel_pressed again.
4417 */
4418 end_time = PQgetCurrentTimeUSec() + 1000000;
4419 rc = PQsocketPoll(sock, forRead, !forRead, end_time);
4420 if (rc == -1)
4421 return;
4422
4423 switch (PQconnectPoll(conn))
4424 {
4425 case PGRES_POLLING_OK:
4427 return;
4429 forRead = true;
4430 continue;
4432 forRead = false;
4433 continue;
4436 }
4437 }
4438}
4439
4440void
4442{
4443 if (!pset.quiet && !pset.notty)
4444 {
4446 char cverbuf[32];
4447 char sverbuf[32];
4448
4449 if (pset.sversion != client_ver)
4450 {
4451 const char *server_version;
4452
4453 /* Try to get full text form, might include "devel" etc */
4454 server_version = PQparameterStatus(pset.db, "server_version");
4455 /* Otherwise fall back on pset.sversion */
4456 if (!server_version)
4457 {
4459 sverbuf, sizeof(sverbuf));
4461 }
4462
4463 printf(_("%s (%s, server %s)\n"),
4465 }
4466 /* For version match, only print psql banner on startup. */
4467 else if (in_startup)
4468 printf("%s (%s)\n", pset.progname, PG_VERSION);
4469
4470 /*
4471 * Warn if server's major version is newer than ours, or if server
4472 * predates our support cutoff (currently 10).
4473 */
4474 if (pset.sversion / 100 > client_ver / 100 ||
4475 pset.sversion < 100000)
4476 printf(_("WARNING: %s major version %s, server major version %s.\n"
4477 " Some psql features might not work.\n"),
4478 pset.progname,
4480 cverbuf, sizeof(cverbuf)),
4482 sverbuf, sizeof(sverbuf)));
4483
4484#ifdef WIN32
4485 if (in_startup)
4487#endif
4488 printSSLInfo();
4489 printGSSInfo();
4490 }
4491}
4492
4493
4494/*
4495 * printSSLInfo
4496 *
4497 * Prints information about the current SSL connection, if SSL is in use
4498 */
4499static void
4501{
4502 const char *protocol;
4503 const char *cipher;
4504 const char *compression;
4505 const char *alpn;
4506
4507 if (!PQsslInUse(pset.db))
4508 return; /* no SSL */
4509
4510 protocol = PQsslAttribute(pset.db, "protocol");
4511 cipher = PQsslAttribute(pset.db, "cipher");
4512 compression = PQsslAttribute(pset.db, "compression");
4513 alpn = PQsslAttribute(pset.db, "alpn");
4514
4515 printf(_("SSL connection (protocol: %s, cipher: %s, compression: %s, ALPN: %s)\n"),
4516 protocol ? protocol : _("unknown"),
4517 cipher ? cipher : _("unknown"),
4518 (compression && strcmp(compression, "off") != 0) ? _("on") : _("off"),
4519 (alpn && alpn[0] != '\0') ? alpn : _("none"));
4520}
4521
4522/*
4523 * printGSSInfo
4524 *
4525 * Prints information about the current GSSAPI connection, if GSSAPI encryption is in use
4526 */
4527static void
4529{
4530 if (!PQgssEncInUse(pset.db))
4531 return; /* no GSSAPI encryption in use */
4532
4533 printf(_("GSSAPI-encrypted connection\n"));
4534}
4535
4536
4537/*
4538 * checkWin32Codepage
4539 *
4540 * Prints a warning when win32 console codepage differs from Windows codepage
4541 */
4542#ifdef WIN32
4543static void
4545{
4546 unsigned int wincp,
4547 concp;
4548
4549 wincp = GetACP();
4550 concp = GetConsoleCP();
4551 if (wincp != concp)
4552 {
4553 printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
4554 " 8-bit characters might not work correctly. See psql reference\n"
4555 " page \"Notes for Windows users\" for details.\n"),
4556 concp, wincp);
4557 }
4558}
4559#endif
4560
4561
4562/*
4563 * SyncVariables
4564 *
4565 * Make psql's internal variables agree with connection state upon
4566 * establishing a new connection.
4567 */
4568void
4570{
4571 char vbuf[32];
4572 const char *server_version;
4573 char *service_name;
4574 char *service_file;
4575
4576 /* get stuff from connection */
4580
4582
4583 SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
4584 SetVariable(pset.vars, "USER", PQuser(pset.db));
4585 SetVariable(pset.vars, "HOST", PQhost(pset.db));
4586 SetVariable(pset.vars, "PORT", PQport(pset.db));
4588
4589 service_name = get_conninfo_value("service");
4590 SetVariable(pset.vars, "SERVICE", service_name);
4591 if (service_name)
4593
4594 service_file = get_conninfo_value("servicefile");
4595 SetVariable(pset.vars, "SERVICEFILE", service_file);
4596 if (service_file)
4598
4599 /* this bit should match connection_warnings(): */
4600 /* Try to get full text form of version, might include "devel" etc */
4601 server_version = PQparameterStatus(pset.db, "server_version");
4602 /* Otherwise fall back on pset.sversion */
4603 if (!server_version)
4604 {
4605 formatPGVersionNumber(pset.sversion, true, vbuf, sizeof(vbuf));
4607 }
4608 SetVariable(pset.vars, "SERVER_VERSION_NAME", server_version);
4609
4610 snprintf(vbuf, sizeof(vbuf), "%d", pset.sversion);
4611 SetVariable(pset.vars, "SERVER_VERSION_NUM", vbuf);
4612
4613 /* send stuff to it, too */
4616}
4617
4618/*
4619 * UnsyncVariables
4620 *
4621 * Clear variables that should be not be set when there is no connection.
4622 */
4623void
4625{
4626 SetVariable(pset.vars, "DBNAME", NULL);
4627 SetVariable(pset.vars, "SERVICE", NULL);
4628 SetVariable(pset.vars, "SERVICEFILE", NULL);
4629 SetVariable(pset.vars, "USER", NULL);
4630 SetVariable(pset.vars, "HOST", NULL);
4631 SetVariable(pset.vars, "PORT", NULL);
4632 SetVariable(pset.vars, "ENCODING", NULL);
4633 SetVariable(pset.vars, "SERVER_VERSION_NAME", NULL);
4634 SetVariable(pset.vars, "SERVER_VERSION_NUM", NULL);
4635}
4636
4637
4638/*
4639 * helper for do_edit(): actually invoke the editor
4640 *
4641 * Returns true on success, false if we failed to invoke the editor or
4642 * it returned nonzero status. (An error message is printed for failed-
4643 * to-invoke cases, but not if the editor returns nonzero status.)
4644 */
4645static bool
4646editFile(const char *fname, int lineno)
4647{
4648 const char *editorName;
4649 const char *editor_lineno_arg = NULL;
4650 char *sys;
4651 int result;
4652
4653 Assert(fname != NULL);
4654
4655 /* Find an editor to use */
4656 editorName = getenv("PSQL_EDITOR");
4657 if (!editorName)
4658 editorName = getenv("EDITOR");
4659 if (!editorName)
4660 editorName = getenv("VISUAL");
4661 if (!editorName)
4663
4664 /* Get line number argument, if we need it. */
4665 if (lineno > 0)
4666 {
4667 editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
4668#ifdef DEFAULT_EDITOR_LINENUMBER_ARG
4669 if (!editor_lineno_arg)
4671#endif
4672 if (!editor_lineno_arg)
4673 {
4674 pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number");
4675 return false;
4676 }
4677 }
4678
4679 /*
4680 * On Unix the EDITOR value should *not* be quoted, since it might include
4681 * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
4682 * if necessary. But this policy is not very workable on Windows, due to
4683 * severe brain damage in their command shell plus the fact that standard
4684 * program paths include spaces.
4685 */
4686#ifndef WIN32
4687 if (lineno > 0)
4688 sys = psprintf("exec %s %s%d '%s'",
4689 editorName, editor_lineno_arg, lineno, fname);
4690 else
4691 sys = psprintf("exec %s '%s'",
4692 editorName, fname);
4693#else
4694 if (lineno > 0)
4695 sys = psprintf("\"%s\" %s%d \"%s\"",
4696 editorName, editor_lineno_arg, lineno, fname);
4697 else
4698 sys = psprintf("\"%s\" \"%s\"",
4699 editorName, fname);
4700#endif
4701 fflush(NULL);
4702 result = system(sys);
4703 if (result == -1)
4704 pg_log_error("could not start editor \"%s\"", editorName);
4705 else if (result == 127)
4706 pg_log_error("could not start /bin/sh");
4707 pfree(sys);
4708
4709 return result == 0;
4710}
4711
4712
4713/*
4714 * do_edit -- handler for \e
4715 *
4716 * If you do not specify a filename, the current query buffer will be copied
4717 * into a temporary file.
4718 *
4719 * After this function is done, the resulting file will be copied back into the
4720 * query buffer. As an exception to this, the query buffer will be emptied
4721 * if the file was not modified (or the editor failed) and the caller passes
4722 * "discard_on_quit" = true.
4723 *
4724 * If "edited" isn't NULL, *edited will be set to true if the query buffer
4725 * is successfully replaced.
4726 */
4727static bool
4729 int lineno, bool discard_on_quit, bool *edited)
4730{
4731 char fnametmp[MAXPGPATH];
4732 FILE *stream = NULL;
4733 const char *fname;
4734 bool error = false;
4735 int fd;
4736 struct stat before,
4737 after;
4738
4739 if (filename_arg)
4740 fname = filename_arg;
4741 else
4742 {
4743 /* make a temp file to edit */
4744#ifndef WIN32
4745 const char *tmpdir = getenv("TMPDIR");
4746
4747 if (!tmpdir)
4748 tmpdir = "/tmp";
4749#else
4750 char tmpdir[MAXPGPATH];
4751 int ret;
4752
4754 if (ret == 0 || ret > MAXPGPATH)
4755 {
4756 pg_log_error("could not locate temporary directory: %s",
4757 !ret ? strerror(errno) : "");
4758 return false;
4759 }
4760#endif
4761
4762 /*
4763 * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
4764 * current directory to the supplied path unless we use only
4765 * backslashes, so we do that.
4766 */
4767#ifndef WIN32
4768 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
4769 "/", (int) getpid());
4770#else
4771 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
4772 "" /* trailing separator already present */ , (int) getpid());
4773#endif
4774
4775 fname = (const char *) fnametmp;
4776
4777 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
4778 if (fd != -1)
4779 stream = fdopen(fd, "w");
4780
4781 if (fd == -1 || !stream)
4782 {
4783 pg_log_error("could not open temporary file \"%s\": %m", fname);
4784 error = true;
4785 }
4786 else
4787 {
4788 unsigned int ql = query_buf->len;
4789
4790 /* force newline-termination of what we send to editor */
4791 if (ql > 0 && query_buf->data[ql - 1] != '\n')
4792 {
4794 ql++;
4795 }
4796
4797 if (fwrite(query_buf->data, 1, ql, stream) != ql)
4798 {
4799 pg_log_error("%s: %m", fname);
4800
4801 if (fclose(stream) != 0)
4802 pg_log_error("%s: %m", fname);
4803
4804 if (remove(fname) != 0)
4805 pg_log_error("%s: %m", fname);
4806
4807 error = true;
4808 }
4809 else if (fclose(stream) != 0)
4810 {
4811 pg_log_error("%s: %m", fname);
4812 if (remove(fname) != 0)
4813 pg_log_error("%s: %m", fname);
4814 error = true;
4815 }
4816 else
4817 {
4818 struct utimbuf ut;
4819
4820 /*
4821 * Try to set the file modification time of the temporary file
4822 * a few seconds in the past. Otherwise, the low granularity
4823 * (one second, or even worse on some filesystems) that we can
4824 * portably measure with stat(2) could lead us to not
4825 * recognize a modification, if the user typed very quickly.
4826 *
4827 * This is a rather unlikely race condition, so don't error
4828 * out if the utime(2) call fails --- that would make the cure
4829 * worse than the disease.
4830 */
4831 ut.modtime = ut.actime = time(NULL) - 2;
4832 (void) utime(fname, &ut);
4833 }
4834 }
4835 }
4836
4837 if (!error && stat(fname, &before) != 0)
4838 {
4839 pg_log_error("%s: %m", fname);
4840 error = true;
4841 }
4842
4843 /* call editor */
4844 if (!error)
4845 error = !editFile(fname, lineno);
4846
4847 if (!error && stat(fname, &after) != 0)
4848 {
4849 pg_log_error("%s: %m", fname);
4850 error = true;
4851 }
4852
4853 /* file was edited if the size or modification time has changed */
4854 if (!error &&
4855 (before.st_size != after.st_size ||
4856 before.st_mtime != after.st_mtime))
4857 {
4858 stream = fopen(fname, PG_BINARY_R);
4859 if (!stream)
4860 {
4861 pg_log_error("%s: %m", fname);
4862 error = true;
4863 }
4864 else
4865 {
4866 /* read file back into query_buf */
4867 char line[1024];
4868
4870 while (fgets(line, sizeof(line), stream) != NULL)
4872
4873 if (ferror(stream))
4874 {
4875 pg_log_error("%s: %m", fname);
4876 error = true;
4878 }
4879 else if (edited)
4880 {
4881 *edited = true;
4882 }
4883
4884 fclose(stream);
4885 }
4886 }
4887 else
4888 {
4889 /*
4890 * If the file was not modified, and the caller requested it, discard
4891 * the query buffer.
4892 */
4893 if (discard_on_quit)
4895 }
4896
4897 /* remove temp file */
4898 if (!filename_arg)
4899 {
4900 if (remove(fname) == -1)
4901 {
4902 pg_log_error("%s: %m", fname);
4903 error = true;
4904 }
4905 }
4906
4907 return !error;
4908}
4909
4910
4911
4912/*
4913 * process_file
4914 *
4915 * Reads commands from filename and passes them to the main processing loop.
4916 * Handler for \i and \ir, but can be used for other things as well. Returns
4917 * MainLoop() error code.
4918 *
4919 * If use_relative_path is true and filename is not an absolute path, then open
4920 * the file from where the currently processed file (if any) is located.
4921 */
4922int
4924{
4925 FILE *fd;
4926 int result;
4927 char *oldfilename;
4928 char relpath[MAXPGPATH];
4929
4930 if (!filename)
4931 {
4932 fd = stdin;
4933 filename = NULL;
4934 }
4935 else if (strcmp(filename, "-") != 0)
4936 {
4938
4939 /*
4940 * If we were asked to resolve the pathname relative to the location
4941 * of the currently executing script, and there is one, and this is a
4942 * relative pathname, then prepend all but the last pathname component
4943 * of the current script to this pathname.
4944 */
4947 {
4952
4953 filename = relpath;
4954 }
4955
4957
4958 if (!fd)
4959 {
4960 pg_log_error("%s: %m", filename);
4961 return EXIT_FAILURE;
4962 }
4963 }
4964 else
4965 {
4966 fd = stdin;
4967 filename = "<stdin>"; /* for future error messages */
4968 }
4969
4972
4974
4975 result = MainLoop(fd);
4976
4977 if (fd != stdin)
4978 fclose(fd);
4979
4981
4983
4984 return result;
4985}
4986
4987
4988
4989static const char *
4991{
4992 switch (in)
4993 {
4994 case PRINT_NOTHING:
4995 return "nothing";
4996 break;
4997 case PRINT_ALIGNED:
4998 return "aligned";
4999 break;
5000 case PRINT_ASCIIDOC:
5001 return "asciidoc";
5002 break;
5003 case PRINT_CSV:
5004 return "csv";
5005 break;
5006 case PRINT_HTML:
5007 return "html";
5008 break;
5009 case PRINT_LATEX:
5010 return "latex";
5011 break;
5013 return "latex-longtable";
5014 break;
5015 case PRINT_TROFF_MS:
5016 return "troff-ms";
5017 break;
5018 case PRINT_UNALIGNED:
5019 return "unaligned";
5020 break;
5021 case PRINT_WRAPPED:
5022 return "wrapped";
5023 break;
5024 }
5025 return "unknown";
5026}
5027
5028/*
5029 * Parse entered Unicode linestyle. If ok, update *linestyle and return
5030 * true, else return false.
5031 */
5032static bool
5033set_unicode_line_style(const char *value, size_t vallen,
5035{
5036 if (pg_strncasecmp("single", value, vallen) == 0)
5038 else if (pg_strncasecmp("double", value, vallen) == 0)
5040 else
5041 return false;
5042 return true;
5043}
5044
5045static const char *
5047{
5048 switch (linestyle)
5049 {
5051 return "single";
5052 break;
5054 return "double";
5055 break;
5056 }
5057 return "unknown";
5058}
5059
5060/*
5061 * do_pset
5062 *
5063 * Performs the assignment "param = value", where value could be NULL;
5064 * for some params that has an effect such as inversion, for others
5065 * it does nothing.
5066 *
5067 * Adjusts the state of the formatting options at *popt. (In practice that
5068 * is always pset.popt, but maybe someday it could be different.)
5069 *
5070 * If successful and quiet is false, then invokes printPsetInfo() to report
5071 * the change.
5072 *
5073 * Returns true if successful, else false (eg for invalid param or value).
5074 */
5075bool
5076do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
5077{
5078 size_t vallen = 0;
5079
5080 Assert(param != NULL);
5081
5082 if (value)
5083 vallen = strlen(value);
5084
5085 /* set format */
5086 if (strcmp(param, "format") == 0)
5087 {
5088 static const struct fmt
5089 {
5090 const char *name;
5091 enum printFormat number;
5092 } formats[] =
5093 {
5094 /* remember to update error message below when adding more */
5095 {"aligned", PRINT_ALIGNED},
5096 {"asciidoc", PRINT_ASCIIDOC},
5097 {"csv", PRINT_CSV},
5098 {"html", PRINT_HTML},
5099 {"latex", PRINT_LATEX},
5100 {"troff-ms", PRINT_TROFF_MS},
5101 {"unaligned", PRINT_UNALIGNED},
5102 {"wrapped", PRINT_WRAPPED}
5103 };
5104
5105 if (!value)
5106 ;
5107 else
5108 {
5109 int match_pos = -1;
5110
5111 for (size_t i = 0; i < lengthof(formats); i++)
5112 {
5113 if (pg_strncasecmp(formats[i].name, value, vallen) == 0)
5114 {
5115 if (match_pos < 0)
5116 match_pos = i;
5117 else
5118 {
5119 pg_log_error("\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"",
5120 value,
5121 formats[match_pos].name, formats[i].name);
5122 return false;
5123 }
5124 }
5125 }
5126 if (match_pos >= 0)
5127 popt->topt.format = formats[match_pos].number;
5128 else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
5129 {
5130 /*
5131 * We must treat latex-longtable specially because latex is a
5132 * prefix of it; if both were in the table above, we'd think
5133 * "latex" is ambiguous.
5134 */
5136 }
5137 else
5138 {
5139 pg_log_error("\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped");
5140 return false;
5141 }
5142 }
5143 }
5144
5145 /* set table line style */
5146 else if (strcmp(param, "linestyle") == 0)
5147 {
5148 if (!value)
5149 ;
5150 else if (pg_strncasecmp("ascii", value, vallen) == 0)
5152 else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
5154 else if (pg_strncasecmp("unicode", value, vallen) == 0)
5155 popt->topt.line_style = &pg_utf8format;
5156 else
5157 {
5158 pg_log_error("\\pset: allowed line styles are ascii, old-ascii, unicode");
5159 return false;
5160 }
5161 }
5162
5163 /* set unicode border line style */
5164 else if (strcmp(param, "unicode_border_linestyle") == 0)
5165 {
5166 if (!value)
5167 ;
5168 else if (set_unicode_line_style(value, vallen,
5170 refresh_utf8format(&(popt->topt));
5171 else
5172 {
5173 pg_log_error("\\pset: allowed Unicode border line styles are single, double");
5174 return false;
5175 }
5176 }
5177
5178 /* set unicode column line style */
5179 else if (strcmp(param, "unicode_column_linestyle") == 0)
5180 {
5181 if (!value)
5182 ;
5183 else if (set_unicode_line_style(value, vallen,
5185 refresh_utf8format(&(popt->topt));
5186 else
5187 {
5188 pg_log_error("\\pset: allowed Unicode column line styles are single, double");
5189 return false;
5190 }
5191 }
5192
5193 /* set unicode header line style */
5194 else if (strcmp(param, "unicode_header_linestyle") == 0)
5195 {
5196 if (!value)
5197 ;
5198 else if (set_unicode_line_style(value, vallen,
5200 refresh_utf8format(&(popt->topt));
5201 else
5202 {
5203 pg_log_error("\\pset: allowed Unicode header line styles are single, double");
5204 return false;
5205 }
5206 }
5207
5208 /* set border style/width */
5209 else if (strcmp(param, "border") == 0)
5210 {
5211 if (value)
5212 popt->topt.border = atoi(value);
5213 }
5214
5215 /* set expanded/vertical mode */
5216 else if (strcmp(param, "x") == 0 ||
5217 strcmp(param, "expanded") == 0 ||
5218 strcmp(param, "vertical") == 0)
5219 {
5220 if (value && pg_strcasecmp(value, "auto") == 0)
5221 popt->topt.expanded = 2;
5222 else if (value)
5223 {
5224 bool on_off;
5225
5227 popt->topt.expanded = on_off ? 1 : 0;
5228 else
5229 {
5230 PsqlVarEnumError(param, value, "on, off, auto");
5231 return false;
5232 }
5233 }
5234 else
5235 popt->topt.expanded = !popt->topt.expanded;
5236 }
5237
5238 /* header line width in expanded mode */
5239 else if (strcmp(param, "xheader_width") == 0)
5240 {
5241 if (!value)
5242 ;
5243 else if (pg_strcasecmp(value, "full") == 0)
5245 else if (pg_strcasecmp(value, "column") == 0)
5247 else if (pg_strcasecmp(value, "page") == 0)
5249 else
5250 {
5251 int intval = atoi(value);
5252
5253 if (intval == 0)
5254 {
5255 pg_log_error("\\pset: allowed xheader_width values are \"%s\" (default), \"%s\", \"%s\", or a number specifying the exact width", "full", "column", "page");
5256 return false;
5257 }
5258
5260 popt->topt.expanded_header_exact_width = intval;
5261 }
5262 }
5263
5264 /* field separator for CSV format */
5265 else if (strcmp(param, "csv_fieldsep") == 0)
5266 {
5267 if (value)
5268 {
5269 /* CSV separator has to be a one-byte character */
5270 if (strlen(value) != 1)
5271 {
5272 pg_log_error("\\pset: csv_fieldsep must be a single one-byte character");
5273 return false;
5274 }
5275 if (value[0] == '"' || value[0] == '\n' || value[0] == '\r')
5276 {
5277 pg_log_error("\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return");
5278 return false;
5279 }
5280 popt->topt.csvFieldSep[0] = value[0];
5281 }
5282 }
5283
5284 /* locale-aware numeric output */
5285 else if (strcmp(param, "numericlocale") == 0)
5286 {
5287 if (value)
5288 return ParseVariableBool(value, param, &popt->topt.numericLocale);
5289 else
5290 popt->topt.numericLocale = !popt->topt.numericLocale;
5291 }
5292
5293 /* null display */
5294 else if (strcmp(param, "null") == 0)
5295 {
5296 if (value)
5297 {
5298 free(popt->nullPrint);
5299 popt->nullPrint = pg_strdup(value);
5300 }
5301 }
5302
5303 /* 'false' display */
5304 else if (strcmp(param, "display_false") == 0)
5305 {
5306 if (value)
5307 {
5308 free(popt->falsePrint);
5309 popt->falsePrint = pg_strdup(value);
5310 }
5311 }
5312
5313 /* 'true' display */
5314 else if (strcmp(param, "display_true") == 0)
5315 {
5316 if (value)
5317 {
5318 free(popt->truePrint);
5319 popt->truePrint = pg_strdup(value);
5320 }
5321 }
5322
5323 /* field separator for unaligned text */
5324 else if (strcmp(param, "fieldsep") == 0)
5325 {
5326 if (value)
5327 {
5328 free(popt->topt.fieldSep.separator);
5330 popt->topt.fieldSep.separator_zero = false;
5331 }
5332 }
5333
5334 else if (strcmp(param, "fieldsep_zero") == 0)
5335 {
5336 free(popt->topt.fieldSep.separator);
5337 popt->topt.fieldSep.separator = NULL;
5338 popt->topt.fieldSep.separator_zero = true;
5339 }
5340
5341 /* record separator for unaligned text */
5342 else if (strcmp(param, "recordsep") == 0)
5343 {
5344 if (value)
5345 {
5348 popt->topt.recordSep.separator_zero = false;
5349 }
5350 }
5351
5352 else if (strcmp(param, "recordsep_zero") == 0)
5353 {
5355 popt->topt.recordSep.separator = NULL;
5356 popt->topt.recordSep.separator_zero = true;
5357 }
5358
5359 /* toggle between full and tuples-only format */
5360 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
5361 {
5362 if (value)
5363 return ParseVariableBool(value, param, &popt->topt.tuples_only);
5364 else
5365 popt->topt.tuples_only = !popt->topt.tuples_only;
5366 }
5367
5368 /* set title override */
5369 else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
5370 {
5371 free(popt->title);
5372 if (!value)
5373 popt->title = NULL;
5374 else
5375 popt->title = pg_strdup(value);
5376 }
5377
5378 /* set HTML table tag options */
5379 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
5380 {
5381 free(popt->topt.tableAttr);
5382 if (!value)
5383 popt->topt.tableAttr = NULL;
5384 else
5385 popt->topt.tableAttr = pg_strdup(value);
5386 }
5387
5388 /* toggle use of pager */
5389 else if (strcmp(param, "pager") == 0)
5390 {
5391 if (value && pg_strcasecmp(value, "always") == 0)
5392 popt->topt.pager = 2;
5393 else if (value)
5394 {
5395 bool on_off;
5396
5398 {
5399 PsqlVarEnumError(param, value, "on, off, always");
5400 return false;
5401 }
5402 popt->topt.pager = on_off ? 1 : 0;
5403 }
5404 else if (popt->topt.pager == 1)
5405 popt->topt.pager = 0;
5406 else
5407 popt->topt.pager = 1;
5408 }
5409
5410 /* set minimum lines for pager use */
5411 else if (strcmp(param, "pager_min_lines") == 0)
5412 {
5413 if (value &&
5414 !ParseVariableNum(value, "pager_min_lines", &popt->topt.pager_min_lines))
5415 return false;
5416 }
5417
5418 /* disable "(x rows)" footer */
5419 else if (strcmp(param, "footer") == 0)
5420 {
5421 if (value)
5422 return ParseVariableBool(value, param, &popt->topt.default_footer);
5423 else
5424 popt->topt.default_footer = !popt->topt.default_footer;
5425 }
5426
5427 /* set border style/width */
5428 else if (strcmp(param, "columns") == 0)
5429 {
5430 if (value)
5431 popt->topt.columns = atoi(value);
5432 }
5433 else
5434 {
5435 pg_log_error("\\pset: unknown option: %s", param);
5436 return false;
5437 }
5438
5439 if (!quiet)
5440 printPsetInfo(param, &pset.popt);
5441
5442 return true;
5443}
5444
5445/*
5446 * printPsetInfo: print the state of the "param" formatting parameter in popt.
5447 */
5448static bool
5449printPsetInfo(const char *param, printQueryOpt *popt)
5450{
5451 Assert(param != NULL);
5452
5453 /* show border style/width */
5454 if (strcmp(param, "border") == 0)
5455 printf(_("Border style is %d.\n"), popt->topt.border);
5456
5457 /* show the target width for the wrapped format */
5458 else if (strcmp(param, "columns") == 0)
5459 {
5460 if (!popt->topt.columns)
5461 printf(_("Target width is unset.\n"));
5462 else
5463 printf(_("Target width is %d.\n"), popt->topt.columns);
5464 }
5465
5466 /* show expanded/vertical mode */
5467 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
5468 {
5469 if (popt->topt.expanded == 1)
5470 printf(_("Expanded display is on.\n"));
5471 else if (popt->topt.expanded == 2)
5472 printf(_("Expanded display is used automatically.\n"));
5473 else
5474 printf(_("Expanded display is off.\n"));
5475 }
5476
5477 /* show xheader width value */
5478 else if (strcmp(param, "xheader_width") == 0)
5479 {
5481 printf(_("Expanded header width is \"%s\".\n"), "full");
5483 printf(_("Expanded header width is \"%s\".\n"), "column");
5485 printf(_("Expanded header width is \"%s\".\n"), "page");
5487 printf(_("Expanded header width is %d.\n"), popt->topt.expanded_header_exact_width);
5488 }
5489
5490 /* show field separator for CSV format */
5491 else if (strcmp(param, "csv_fieldsep") == 0)
5492 {
5493 printf(_("Field separator for CSV is \"%s\".\n"),
5494 popt->topt.csvFieldSep);
5495 }
5496
5497 /* show boolean 'false' display */
5498 else if (strcmp(param, "display_false") == 0)
5499 {
5500 printf(_("Boolean false display is \"%s\".\n"),
5501 popt->falsePrint ? popt->falsePrint : "f");
5502 }
5503
5504 /* show boolean 'true' display */
5505 else if (strcmp(param, "display_true") == 0)
5506 {
5507 printf(_("Boolean true display is \"%s\".\n"),
5508 popt->truePrint ? popt->truePrint : "t");
5509 }
5510
5511 /* show field separator for unaligned text */
5512 else if (strcmp(param, "fieldsep") == 0)
5513 {
5514 if (popt->topt.fieldSep.separator_zero)
5515 printf(_("Field separator is zero byte.\n"));
5516 else
5517 printf(_("Field separator is \"%s\".\n"),
5518 popt->topt.fieldSep.separator);
5519 }
5520
5521 else if (strcmp(param, "fieldsep_zero") == 0)
5522 {
5523 printf(_("Field separator is zero byte.\n"));
5524 }
5525
5526 /* show disable "(x rows)" footer */
5527 else if (strcmp(param, "footer") == 0)
5528 {
5529 if (popt->topt.default_footer)
5530 printf(_("Default footer is on.\n"));
5531 else
5532 printf(_("Default footer is off.\n"));
5533 }
5534
5535 /* show format */
5536 else if (strcmp(param, "format") == 0)
5537 {
5538 printf(_("Output format is %s.\n"), _align2string(popt->topt.format));
5539 }
5540
5541 /* show table line style */
5542 else if (strcmp(param, "linestyle") == 0)
5543 {
5544 printf(_("Line style is %s.\n"),
5545 get_line_style(&popt->topt)->name);
5546 }
5547
5548 /* show null display */
5549 else if (strcmp(param, "null") == 0)
5550 {
5551 printf(_("Null display is \"%s\".\n"),
5552 popt->nullPrint ? popt->nullPrint : "");
5553 }
5554
5555 /* show locale-aware numeric output */
5556 else if (strcmp(param, "numericlocale") == 0)
5557 {
5558 if (popt->topt.numericLocale)
5559 printf(_("Locale-adjusted numeric output is on.\n"));
5560 else
5561 printf(_("Locale-adjusted numeric output is off.\n"));
5562 }
5563
5564 /* show toggle use of pager */
5565 else if (strcmp(param, "pager") == 0)
5566 {
5567 if (popt->topt.pager == 1)
5568 printf(_("Pager is used for long output.\n"));
5569 else if (popt->topt.pager == 2)
5570 printf(_("Pager is always used.\n"));
5571 else
5572 printf(_("Pager usage is off.\n"));
5573 }
5574
5575 /* show minimum lines for pager use */
5576 else if (strcmp(param, "pager_min_lines") == 0)
5577 {
5578 printf(ngettext("Pager won't be used for less than %d line.\n",
5579 "Pager won't be used for less than %d lines.\n",
5580 popt->topt.pager_min_lines),
5581 popt->topt.pager_min_lines);
5582 }
5583
5584 /* show record separator for unaligned text */
5585 else if (strcmp(param, "recordsep") == 0)
5586 {
5587 if (popt->topt.recordSep.separator_zero)
5588 printf(_("Record separator is zero byte.\n"));
5589 else if (strcmp(popt->topt.recordSep.separator, "\n") == 0)
5590 printf(_("Record separator is <newline>.\n"));
5591 else
5592 printf(_("Record separator is \"%s\".\n"),
5593 popt->topt.recordSep.separator);
5594 }
5595
5596 else if (strcmp(param, "recordsep_zero") == 0)
5597 {
5598 printf(_("Record separator is zero byte.\n"));
5599 }
5600
5601 /* show HTML table tag options */
5602 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
5603 {
5604 if (popt->topt.tableAttr)
5605 printf(_("Table attributes are \"%s\".\n"),
5606 popt->topt.tableAttr);
5607 else
5608 printf(_("Table attributes unset.\n"));
5609 }
5610
5611 /* show title override */
5612 else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
5613 {
5614 if (popt->title)
5615 printf(_("Title is \"%s\".\n"), popt->title);
5616 else
5617 printf(_("Title is unset.\n"));
5618 }
5619
5620 /* show toggle between full and tuples-only format */
5621 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
5622 {
5623 if (popt->topt.tuples_only)
5624 printf(_("Tuples only is on.\n"));
5625 else
5626 printf(_("Tuples only is off.\n"));
5627 }
5628
5629 /* Unicode style formatting */
5630 else if (strcmp(param, "unicode_border_linestyle") == 0)
5631 {
5632 printf(_("Unicode border line style is \"%s\".\n"),
5634 }
5635
5636 else if (strcmp(param, "unicode_column_linestyle") == 0)
5637 {
5638 printf(_("Unicode column line style is \"%s\".\n"),
5640 }
5641
5642 else if (strcmp(param, "unicode_header_linestyle") == 0)
5643 {
5644 printf(_("Unicode header line style is \"%s\".\n"),
5646 }
5647
5648 else
5649 {
5650 pg_log_error("\\pset: unknown option: %s", param);
5651 return false;
5652 }
5653
5654 return true;
5655}
5656
5657/*
5658 * savePsetInfo: make a malloc'd copy of the data in *popt.
5659 *
5660 * Possibly this should be somewhere else, but it's a bit specific to psql.
5661 */
5664{
5666
5668
5669 /* Flat-copy all the scalar fields, then duplicate sub-structures. */
5670 memcpy(save, popt, sizeof(printQueryOpt));
5671
5672 /* topt.line_style points to const data that need not be duplicated */
5673 if (popt->topt.fieldSep.separator)
5674 save->topt.fieldSep.separator = pg_strdup(popt->topt.fieldSep.separator);
5675 if (popt->topt.recordSep.separator)
5676 save->topt.recordSep.separator = pg_strdup(popt->topt.recordSep.separator);
5677 if (popt->topt.tableAttr)
5678 save->topt.tableAttr = pg_strdup(popt->topt.tableAttr);
5679 if (popt->nullPrint)
5680 save->nullPrint = pg_strdup(popt->nullPrint);
5681 if (popt->truePrint)
5682 save->truePrint = pg_strdup(popt->truePrint);
5683 if (popt->falsePrint)
5684 save->falsePrint = pg_strdup(popt->falsePrint);
5685 if (popt->title)
5686 save->title = pg_strdup(popt->title);
5687
5688 /*
5689 * footers and translate_columns are never set in psql's print settings,
5690 * so we needn't write code to duplicate them.
5691 */
5692 Assert(popt->footers == NULL);
5693 Assert(popt->translate_columns == NULL);
5694
5695 return save;
5696}
5697
5698/*
5699 * restorePsetInfo: restore *popt from the previously-saved copy *save,
5700 * then free *save.
5701 */
5702void
5704{
5705 /* Free all the old data we're about to overwrite the pointers to. */
5706
5707 /* topt.line_style points to const data that need not be duplicated */
5708 free(popt->topt.fieldSep.separator);
5710 free(popt->topt.tableAttr);
5711 free(popt->nullPrint);
5712 free(popt->truePrint);
5713 free(popt->falsePrint);
5714 free(popt->title);
5715
5716 /*
5717 * footers and translate_columns are never set in psql's print settings,
5718 * so we needn't write code to duplicate them.
5719 */
5720 Assert(popt->footers == NULL);
5721 Assert(popt->translate_columns == NULL);
5722
5723 /* Now we may flat-copy all the fields, including pointers. */
5724 memcpy(popt, save, sizeof(printQueryOpt));
5725
5726 /* Lastly, free "save" ... but its sub-structures now belong to popt. */
5727 free(save);
5728}
5729
5730static const char *
5732{
5733 return val ? "on" : "off";
5734}
5735
5736
5737static char *
5739{
5740 char *ret = pg_malloc(strlen(str) * 2 + 3);
5741 char *r = ret;
5742
5743 *r++ = '\'';
5744
5745 for (; *str; str++)
5746 {
5747 if (*str == '\n')
5748 {
5749 *r++ = '\\';
5750 *r++ = 'n';
5751 }
5752 else if (*str == '\'')
5753 {
5754 *r++ = '\\';
5755 *r++ = '\'';
5756 }
5757 else
5758 *r++ = *str;
5759 }
5760
5761 *r++ = '\'';
5762 *r = '\0';
5763
5764 return ret;
5765}
5766
5767
5768/*
5769 * Return a malloc'ed string for the \pset value.
5770 *
5771 * Note that for some string parameters, print.c distinguishes between unset
5772 * and empty string, but for others it doesn't. This function should produce
5773 * output that produces the correct setting when fed back into \pset.
5774 */
5775static char *
5776pset_value_string(const char *param, printQueryOpt *popt)
5777{
5778 Assert(param != NULL);
5779
5780 if (strcmp(param, "border") == 0)
5781 return psprintf("%d", popt->topt.border);
5782 else if (strcmp(param, "columns") == 0)
5783 return psprintf("%d", popt->topt.columns);
5784 else if (strcmp(param, "csv_fieldsep") == 0)
5785 return pset_quoted_string(popt->topt.csvFieldSep);
5786 else if (strcmp(param, "display_false") == 0)
5787 return pset_quoted_string(popt->falsePrint ? popt->falsePrint : "f");
5788 else if (strcmp(param, "display_true") == 0)
5789 return pset_quoted_string(popt->truePrint ? popt->truePrint : "t");
5790 else if (strcmp(param, "expanded") == 0)
5791 return pstrdup(popt->topt.expanded == 2
5792 ? "auto"
5793 : pset_bool_string(popt->topt.expanded));
5794 else if (strcmp(param, "fieldsep") == 0)
5796 ? popt->topt.fieldSep.separator
5797 : "");
5798 else if (strcmp(param, "fieldsep_zero") == 0)
5800 else if (strcmp(param, "footer") == 0)
5802 else if (strcmp(param, "format") == 0)
5803 return pstrdup(_align2string(popt->topt.format));
5804 else if (strcmp(param, "linestyle") == 0)
5805 return pstrdup(get_line_style(&popt->topt)->name);
5806 else if (strcmp(param, "null") == 0)
5807 return pset_quoted_string(popt->nullPrint
5808 ? popt->nullPrint
5809 : "");
5810 else if (strcmp(param, "numericlocale") == 0)
5812 else if (strcmp(param, "pager") == 0)
5813 return psprintf("%d", popt->topt.pager);
5814 else if (strcmp(param, "pager_min_lines") == 0)
5815 return psprintf("%d", popt->topt.pager_min_lines);
5816 else if (strcmp(param, "recordsep") == 0)
5818 ? popt->topt.recordSep.separator
5819 : "");
5820 else if (strcmp(param, "recordsep_zero") == 0)
5822 else if (strcmp(param, "tableattr") == 0)
5823 return popt->topt.tableAttr ? pset_quoted_string(popt->topt.tableAttr) : pstrdup("");
5824 else if (strcmp(param, "title") == 0)
5825 return popt->title ? pset_quoted_string(popt->title) : pstrdup("");
5826 else if (strcmp(param, "tuples_only") == 0)
5828 else if (strcmp(param, "unicode_border_linestyle") == 0)
5830 else if (strcmp(param, "unicode_column_linestyle") == 0)
5832 else if (strcmp(param, "unicode_header_linestyle") == 0)
5834 else if (strcmp(param, "xheader_width") == 0)
5835 {
5837 return pstrdup("full");
5839 return pstrdup("column");
5841 return pstrdup("page");
5842 else
5843 {
5844 /* must be PRINT_XHEADER_EXACT_WIDTH */
5845 char wbuff[32];
5846
5847 snprintf(wbuff, sizeof(wbuff), "%d",
5849 return pstrdup(wbuff);
5850 }
5851 }
5852 else
5853 return pstrdup("ERROR");
5854}
5855
5856
5857
5858#ifndef WIN32
5859#define DEFAULT_SHELL "/bin/sh"
5860#else
5861/*
5862 * CMD.EXE is in different places in different Win32 releases so we
5863 * have to rely on the path to find it.
5864 */
5865#define DEFAULT_SHELL "cmd.exe"
5866#endif
5867
5868static bool
5869do_shell(const char *command)
5870{
5871 int result;
5872
5873 fflush(NULL);
5874 if (!command)
5875 {
5876 char *sys;
5877 const char *shellName;
5878
5879 shellName = getenv("SHELL");
5880#ifdef WIN32
5881 if (shellName == NULL)
5882 shellName = getenv("COMSPEC");
5883#endif
5884 if (shellName == NULL)
5886
5887 /* See EDITOR handling comment for an explanation */
5888#ifndef WIN32
5889 sys = psprintf("exec %s", shellName);
5890#else
5891 sys = psprintf("\"%s\"", shellName);
5892#endif
5893 result = system(sys);
5894 pfree(sys);
5895 }
5896 else
5897 result = system(command);
5898
5900
5901 if (result == 127 || result == -1)
5902 {
5903 pg_log_error("\\!: failed");
5904 return false;
5905 }
5906 return true;
5907}
5908
5909/*
5910 * do_watch -- handler for \watch
5911 *
5912 * We break this out of exec_command to avoid having to plaster "volatile"
5913 * onto a bunch of exec_command's variables to silence stupider compilers.
5914 *
5915 * "sleep" is the amount of time to sleep during each loop, measured in
5916 * seconds. The internals of this function should use "sleep_ms" for
5917 * precise sleep time calculations.
5918 */
5919static bool
5921{
5922 long sleep_ms = (long) (sleep * 1000);
5924 const char *strftime_fmt;
5925 const char *user_title;
5926 char *title;
5927 const char *pagerprog = NULL;
5928 FILE *pagerpipe = NULL;
5929 int title_len;
5930 int res = 0;
5931 bool done = false;
5932#ifndef WIN32
5936 struct itimerval interval;
5937#endif
5938
5939 if (!query_buf || query_buf->len <= 0)
5940 {
5941 pg_log_error("\\watch cannot be used with an empty query");
5942 return false;
5943 }
5944
5945#ifndef WIN32
5950
5954
5957
5958 /*
5959 * Block SIGALRM and SIGCHLD before we start the timer and the pager (if
5960 * configured), to avoid races. sigwait() will receive them.
5961 */
5963
5964 /*
5965 * Set a timer to interrupt sigwait() so we can run the query at the
5966 * requested intervals.
5967 */
5968 interval.it_value.tv_sec = sleep_ms / 1000;
5969 interval.it_value.tv_usec = (sleep_ms % 1000) * 1000;
5970 interval.it_interval = interval.it_value;
5971 if (setitimer(ITIMER_REAL, &interval, NULL) < 0)
5972 {
5973 pg_log_error("could not set timer: %m");
5974 done = true;
5975 }
5976#endif
5977
5978 /*
5979 * For \watch, we ignore the size of the result and always use the pager
5980 * as long as we're talking to a terminal and "\pset pager" is enabled.
5981 * However, we'll only use the pager identified by PSQL_WATCH_PAGER. We
5982 * ignore the regular PSQL_PAGER or PAGER environment variables, because
5983 * traditional pagers probably won't be very useful for showing a stream
5984 * of results.
5985 */
5986#ifndef WIN32
5987 pagerprog = getenv("PSQL_WATCH_PAGER");
5988 /* if variable is empty or all-white-space, don't use pager */
5989 if (pagerprog && strspn(pagerprog, " \t\r\n") == strlen(pagerprog))
5990 pagerprog = NULL;
5991#endif
5992 if (pagerprog && myopt.topt.pager &&
5993 isatty(fileno(stdin)) && isatty(fileno(stdout)))
5994 {
5995 fflush(NULL);
5997 pagerpipe = popen(pagerprog, "w");
5998
5999 if (!pagerpipe)
6000 /* silently proceed without pager */
6002 }
6003
6004 /*
6005 * Choose format for timestamps. We might eventually make this a \pset
6006 * option. In the meantime, using a variable for the format suppresses
6007 * overly-anal-retentive gcc warnings about %c being Y2K sensitive.
6008 */
6009 strftime_fmt = "%c";
6010
6011 /*
6012 * Set up rendering options, in particular, disable the pager unless
6013 * PSQL_WATCH_PAGER was successfully launched.
6014 */
6015 if (!pagerpipe)
6016 myopt.topt.pager = 0;
6017
6018 /*
6019 * If there's a title in the user configuration, make sure we have room
6020 * for it in the title buffer. Allow 128 bytes for the timestamp plus 128
6021 * bytes for the rest.
6022 */
6023 user_title = myopt.title;
6024 title_len = (user_title ? strlen(user_title) : 0) + 256;
6025 title = pg_malloc(title_len);
6026
6027 /* Loop to run query and then sleep awhile */
6028 while (!done)
6029 {
6030 time_t timer;
6031 char timebuf[128];
6032
6033 /*
6034 * Prepare title for output. Note that we intentionally include a
6035 * newline at the end of the title; this is somewhat historical but it
6036 * makes for reasonably nicely formatted output in simple cases.
6037 */
6038 timer = time(NULL);
6040
6041 if (user_title)
6042 snprintf(title, title_len, _("%s\t%s (every %gs)\n"),
6043 user_title, timebuf, sleep_ms / 1000.0);
6044 else
6045 snprintf(title, title_len, _("%s (every %gs)\n"),
6046 timebuf, sleep_ms / 1000.0);
6047 myopt.title = title;
6048
6049 /* Run the query and print out the result */
6051
6052 /*
6053 * PSQLexecWatch handles the case where we can no longer repeat the
6054 * query, and returns 0 or -1.
6055 */
6056 if (res <= 0)
6057 break;
6058
6059 /* If we have iteration count, check that it's not exceeded yet */
6060 if (iter && (--iter <= 0))
6061 break;
6062
6063 /* Quit if error on pager pipe (probably pager has quit) */
6064 if (pagerpipe && ferror(pagerpipe))
6065 break;
6066
6067 /* Tight loop, no wait needed */
6068 if (sleep_ms == 0)
6069 continue;
6070
6071#ifdef WIN32
6072
6073 /*
6074 * Wait a while before running the query again. Break the sleep into
6075 * short intervals (at most 1s); that's probably unnecessary since
6076 * pg_usleep is interruptible on Windows, but it's cheap insurance.
6077 */
6078 for (long i = sleep_ms; i > 0;)
6079 {
6080 long s = Min(i, 1000L);
6081
6082 pg_usleep(s * 1000L);
6083 if (cancel_pressed)
6084 {
6085 done = true;
6086 break;
6087 }
6088 i -= s;
6089 }
6090#else
6091 /* sigwait() will handle SIGINT. */
6093 if (cancel_pressed)
6094 done = true;
6095
6096 /* Wait for SIGINT, SIGCHLD or SIGALRM. */
6097 while (!done)
6098 {
6099 int signal_received;
6100
6102 if (errno != 0)
6103 {
6104 /* Some other signal arrived? */
6105 if (errno == EINTR)
6106 continue;
6107 else
6108 {
6109 pg_log_error("could not wait for signals: %m");
6110 done = true;
6111 break;
6112 }
6113 }
6114 /* On ^C or pager exit, it's time to stop running the query. */
6116 done = true;
6117 /* Otherwise, we must have SIGALRM. Time to run the query again. */
6118 break;
6119 }
6120
6121 /* Unblock SIGINT so that slow queries can be interrupted. */
6123#endif
6124 }
6125
6126 if (pagerpipe)
6127 {
6130 }
6131 else
6132 {
6133 /*
6134 * If the terminal driver echoed "^C", libedit/libreadline might be
6135 * confused about the cursor position. Therefore, inject a newline
6136 * before the next prompt is displayed. We only do this when not
6137 * using a pager, because pagers are expected to restore the screen to
6138 * a sane state on exit.
6139 */
6140 fprintf(stdout, "\n");
6141 fflush(stdout);
6142 }
6143
6144#ifndef WIN32
6145 /* Disable the interval timer. */
6146 memset(&interval, 0, sizeof(interval));
6148 /* Unblock SIGINT, SIGCHLD and SIGALRM. */
6150#endif
6151
6152 pg_free(title);
6153 return (res >= 0);
6154}
6155
6156/*
6157 * a little code borrowed from PSQLexec() to manage ECHO_HIDDEN output.
6158 * returns true unless we have ECHO_HIDDEN_NOEXEC.
6159 */
6160static bool
6161echo_hidden_command(const char *query)
6162{
6164 {
6165 printf(_("/**** INTERNAL QUERY ****/\n"
6166 "%s\n"
6167 "/************************/\n\n"), query);
6168 fflush(stdout);
6169 if (pset.logfile)
6170 {
6172 _("/**** INTERNAL QUERY ****/\n"
6173 "%s\n"
6174 "/************************/\n\n"), query);
6176 }
6177
6179 return false;
6180 }
6181 return true;
6182}
6183
6184/*
6185 * Look up the object identified by obj_type and desc. If successful,
6186 * store its OID in *obj_oid and return true, else return false.
6187 *
6188 * Note that we'll fail if the object doesn't exist OR if there are multiple
6189 * matching candidates OR if there's something syntactically wrong with the
6190 * object description; unfortunately it can be hard to tell the difference.
6191 */
6192static bool
6194 Oid *obj_oid)
6195{
6196 bool result = true;
6198 PGresult *res;
6199
6200 switch (obj_type)
6201 {
6202 case EditableFunction:
6203
6204 /*
6205 * We have a function description, e.g. "x" or "x(int)". Issue a
6206 * query to retrieve the function's OID using a cast to regproc or
6207 * regprocedure (as appropriate).
6208 */
6209 printfPQExpBuffer(query, "/* %s */\n", _("Get function's OID"));
6210 appendPQExpBufferStr(query, "SELECT ");
6211 appendStringLiteralConn(query, desc, pset.db);
6212 appendPQExpBuffer(query, "::pg_catalog.%s::pg_catalog.oid",
6213 strchr(desc, '(') ? "regprocedure" : "regproc");
6214 break;
6215
6216 case EditableView:
6217
6218 /*
6219 * Convert view name (possibly schema-qualified) to OID. Note:
6220 * this code doesn't check if the relation is actually a view.
6221 * We'll detect that in get_create_object_cmd().
6222 */
6223 printfPQExpBuffer(query, "/* %s */\n", _("Get view's OID"));
6224 appendPQExpBufferStr(query, "SELECT ");
6225 appendStringLiteralConn(query, desc, pset.db);
6226 appendPQExpBufferStr(query, "::pg_catalog.regclass::pg_catalog.oid");
6227 break;
6228 }
6229
6230 if (!echo_hidden_command(query->data))
6231 {
6232 destroyPQExpBuffer(query);
6233 return false;
6234 }
6235 res = PQexec(pset.db, query->data);
6236 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
6237 *obj_oid = atooid(PQgetvalue(res, 0, 0));
6238 else
6239 {
6241 result = false;
6242 }
6243
6244 PQclear(res);
6245 destroyPQExpBuffer(query);
6246
6247 return result;
6248}
6249
6250/*
6251 * Construct a "CREATE OR REPLACE ..." command that describes the specified
6252 * database object. If successful, the result is stored in buf.
6253 */
6254static bool
6257{
6258 bool result = true;
6260 PGresult *res;
6261
6262 switch (obj_type)
6263 {
6264 case EditableFunction:
6265 printfPQExpBuffer(query, "/* %s */\n", _("Get function's definition"));
6266 appendPQExpBuffer(query,
6267 "SELECT pg_catalog.pg_get_functiondef(%u)",
6268 oid);
6269 break;
6270
6271 case EditableView:
6272
6273 /*
6274 * pg_get_viewdef() just prints the query, so we must prepend
6275 * CREATE for ourselves. We must fully qualify the view name to
6276 * ensure the right view gets replaced. Also, check relation kind
6277 * to be sure it's a view.
6278 *
6279 * Views may have WITH [LOCAL|CASCADED] CHECK OPTION. These are
6280 * not part of the view definition returned by pg_get_viewdef()
6281 * and so need to be retrieved separately. Materialized views may
6282 * have arbitrary storage parameter reloptions.
6283 */
6284 printfPQExpBuffer(query, "/* %s */\n", _("Get view's definition and details"));
6285 appendPQExpBuffer(query,
6286 "SELECT nspname, relname, relkind, "
6287 "pg_catalog.pg_get_viewdef(c.oid, true), "
6288 "pg_catalog.array_remove(pg_catalog.array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
6289 "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
6290 "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
6291 "FROM pg_catalog.pg_class c "
6292 "LEFT JOIN pg_catalog.pg_namespace n "
6293 "ON c.relnamespace = n.oid WHERE c.oid = %u",
6294 oid);
6295 break;
6296 }
6297
6298 if (!echo_hidden_command(query->data))
6299 {
6300 destroyPQExpBuffer(query);
6301 return false;
6302 }
6303 res = PQexec(pset.db, query->data);
6304 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
6305 {
6307 switch (obj_type)
6308 {
6309 case EditableFunction:
6310 appendPQExpBufferStr(buf, PQgetvalue(res, 0, 0));
6311 break;
6312
6313 case EditableView:
6314 {
6315 char *nspname = PQgetvalue(res, 0, 0);
6316 char *relname = PQgetvalue(res, 0, 1);
6317 char *relkind = PQgetvalue(res, 0, 2);
6318 char *viewdef = PQgetvalue(res, 0, 3);
6319 char *reloptions = PQgetvalue(res, 0, 4);
6320 char *checkoption = PQgetvalue(res, 0, 5);
6321
6322 /*
6323 * If the backend ever supports CREATE OR REPLACE
6324 * MATERIALIZED VIEW, allow that here; but as of today it
6325 * does not, so editing a matview definition in this way
6326 * is impossible.
6327 */
6328 switch (relkind[0])
6329 {
6330#ifdef NOT_USED
6331 case RELKIND_MATVIEW:
6332 appendPQExpBufferStr(buf, "CREATE OR REPLACE MATERIALIZED VIEW ");
6333 break;
6334#endif
6335 case RELKIND_VIEW:
6336 appendPQExpBufferStr(buf, "CREATE OR REPLACE VIEW ");
6337 break;
6338 default:
6339 pg_log_error("\"%s.%s\" is not a view",
6340 nspname, relname);
6341 result = false;
6342 break;
6343 }
6344 appendPQExpBuffer(buf, "%s.", fmtId(nspname));
6346
6347 /* reloptions, if not an empty array "{}" */
6348 if (reloptions != NULL && strlen(reloptions) > 2)
6349 {
6350 appendPQExpBufferStr(buf, "\n WITH (");
6351 if (!appendReloptionsArray(buf, reloptions, "",
6352 pset.encoding,
6354 {
6355 pg_log_error("could not parse reloptions array");
6356 result = false;
6357 }
6359 }
6360
6361 /* View definition from pg_get_viewdef (a SELECT query) */
6362 appendPQExpBuffer(buf, " AS\n%s", viewdef);
6363
6364 /* Get rid of the semicolon that pg_get_viewdef appends */
6365 if (buf->len > 0 && buf->data[buf->len - 1] == ';')
6366 buf->data[--(buf->len)] = '\0';
6367
6368 /* WITH [LOCAL|CASCADED] CHECK OPTION */
6369 if (checkoption && checkoption[0] != '\0')
6370 appendPQExpBuffer(buf, "\n WITH %s CHECK OPTION",
6371 checkoption);
6372 }
6373 break;
6374 }
6375 /* Make sure result ends with a newline */
6376 if (buf->len > 0 && buf->data[buf->len - 1] != '\n')
6378 }
6379 else
6380 {
6382 result = false;
6383 }
6384
6385 PQclear(res);
6386 destroyPQExpBuffer(query);
6387
6388 return result;
6389}
6390
6391/*
6392 * If the given argument of \ef or \ev ends with a line number, delete the line
6393 * number from the argument string and return it as an integer. (We need
6394 * this kluge because we're too lazy to parse \ef's function or \ev's view
6395 * argument carefully --- we just slop it up in OT_WHOLE_LINE mode.)
6396 *
6397 * Returns -1 if no line number is present, 0 on error, or a positive value
6398 * on success.
6399 */
6400static int
6402{
6403 char *c;
6404 int lineno;
6405
6406 if (!obj || obj[0] == '\0')
6407 return -1;
6408
6409 c = obj + strlen(obj) - 1;
6410
6411 /*
6412 * This business of parsing backwards is dangerous as can be in a
6413 * multibyte environment: there is no reason to believe that we are
6414 * looking at the first byte of a character, nor are we necessarily
6415 * working in a "safe" encoding. Fortunately the bitpatterns we are
6416 * looking for are unlikely to occur as non-first bytes, but beware of
6417 * trying to expand the set of cases that can be recognized. We must
6418 * guard the <ctype.h> macros by using isascii() first, too.
6419 */
6420
6421 /* skip trailing whitespace */
6422 while (c > obj && isascii((unsigned char) *c) && isspace((unsigned char) *c))
6423 c--;
6424
6425 /* must have a digit as last non-space char */
6426 if (c == obj || !isascii((unsigned char) *c) || !isdigit((unsigned char) *c))
6427 return -1;
6428
6429 /* find start of digit string */
6430 while (c > obj && isascii((unsigned char) *c) && isdigit((unsigned char) *c))
6431 c--;
6432
6433 /* digits must be separated from object name by space or closing paren */
6434 /* notice also that we are not allowing an empty object name ... */
6435 if (c == obj || !isascii((unsigned char) *c) ||
6436 !(isspace((unsigned char) *c) || *c == ')'))
6437 return -1;
6438
6439 /* parse digit string */
6440 c++;
6441 lineno = atoi(c);
6442 if (lineno < 1)
6443 {
6444 pg_log_error("invalid line number: %s", c);
6445 return 0;
6446 }
6447
6448 /* strip digit string from object name */
6449 *c = '\0';
6450
6451 return lineno;
6452}
6453
6454/*
6455 * Count number of lines in the buffer.
6456 * This is used to test if pager is needed or not.
6457 */
6458static int
6460{
6461 int lineno = 0;
6462 const char *lines = buf->data;
6463
6464 while (*lines != '\0')
6465 {
6466 lineno++;
6467 /* find start of next line */
6468 lines = strchr(lines, '\n');
6469 if (!lines)
6470 break;
6471 lines++;
6472 }
6473
6474 return lineno;
6475}
6476
6477/*
6478 * Write text at *lines to output with line numbers.
6479 *
6480 * For functions, lineno "1" should correspond to the first line of the
6481 * function body; lines before that are unnumbered. We expect that
6482 * pg_get_functiondef() will emit that on a line beginning with "AS ",
6483 * "BEGIN ", or "RETURN ", and that there can be no such line before
6484 * the real start of the function body.
6485 *
6486 * Caution: this scribbles on *lines.
6487 */
6488static void
6489print_with_linenumbers(FILE *output, char *lines, bool is_func)
6490{
6491 bool in_header = is_func;
6492 int lineno = 0;
6493
6494 while (*lines != '\0')
6495 {
6496 char *eol;
6497
6498 if (in_header &&
6499 (strncmp(lines, "AS ", 3) == 0 ||
6500 strncmp(lines, "BEGIN ", 6) == 0 ||
6501 strncmp(lines, "RETURN ", 7) == 0))
6502 in_header = false;
6503
6504 /* increment lineno only for body's lines */
6505 if (!in_header)
6506 lineno++;
6507
6508 /* find and mark end of current line */
6509 eol = strchr(lines, '\n');
6510 if (eol != NULL)
6511 *eol = '\0';
6512
6513 /* show current line as appropriate */
6514 if (in_header)
6515 fprintf(output, " %s\n", lines);
6516 else
6517 fprintf(output, "%-7d %s\n", lineno, lines);
6518
6519 /* advance to next line, if any */
6520 if (eol == NULL)
6521 break;
6522 lines = ++eol;
6523 }
6524}
6525
6526/*
6527 * Report just the primary error; this is to avoid cluttering the output
6528 * with, for instance, a redisplay of the internally generated query
6529 */
6530static void
6532{
6533 PQExpBuffer msg;
6534 const char *fld;
6535
6536 msg = createPQExpBuffer();
6537
6539 if (fld)
6540 printfPQExpBuffer(msg, "%s: ", fld);
6541 else
6542 printfPQExpBuffer(msg, "ERROR: ");
6544 if (fld)
6546 else
6547 appendPQExpBufferStr(msg, "(not available)");
6548 appendPQExpBufferChar(msg, '\n');
6549
6550 pg_log_error("%s", msg->data);
6551
6552 destroyPQExpBuffer(msg);
6553}
void expand_tilde(char **filename)
Definition common.c:2619
PGresult * PSQLexec(const char *query)
Definition common.c:657
volatile sig_atomic_t sigint_interrupt_enabled
Definition common.c:304
char * get_conninfo_value(const char *keyword)
Definition common.c:2582
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:712
void SetShellResultVariables(int wait_result)
Definition common.c:518
void NoticeProcessor(void *arg, const char *message)
Definition common.c:279
void clean_extended_state(void)
Definition common.c:2703
bool standard_strings(void)
Definition common.c:2542
bool setQFout(const char *fname)
Definition common.c:144
bool recognized_connection_string(const char *connstr)
Definition common.c:2747
bool do_copy(const char *args)
Definition copy.c:268
static Datum values[MAXATTR]
Definition bootstrap.c:190
#define Min(x, y)
Definition c.h:1131
#define PG_BINARY_R
Definition c.h:1433
#define ngettext(s, p, n)
Definition c.h:1310
#define Assert(condition)
Definition c.h:1002
#define pg_unreachable()
Definition c.h:426
#define lengthof(array)
Definition c.h:932
void ResetCancelConn(void)
Definition cancel.c:137
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
static backslashResult exec_command_startpipeline(PsqlScanState scan_state, bool active_branch)
Definition command.c:3059
static backslashResult exec_command_endif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition command.c:2290
static backslashResult exec_command_getresults(PsqlScanState scan_state, bool active_branch)
Definition command.c:1928
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:1642
int process_file(char *filename, bool use_relative_path)
Definition command.c:4923
static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition command.c:2481
static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid, PQExpBuffer buf)
Definition command.c:6255
static backslashResult exec_command_html(PsqlScanState scan_state, bool active_branch)
Definition command.c:2043
static bool copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition command.c:3846
static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:1738
static char * pset_value_string(const char *param, printQueryOpt *popt)
Definition command.c:5776
static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch)
Definition command.c:3138
static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
Definition command.c:1874
static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch)
Definition command.c:2023
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:3820
static bool set_unicode_line_style(const char *value, size_t vallen, unicode_linestyle *linestyle)
Definition command.c:5033
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
Definition command.c:5703
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:3719
static bool do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
Definition command.c:5920
static backslashResult exec_command_flushrequest(PsqlScanState scan_state, bool active_branch)
Definition command.c:1713
printQueryOpt * savePsetInfo(const printQueryOpt *popt)
Definition command.c:5663
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:5046
static PQExpBuffer gather_boolean_expression(PsqlScanState scan_state)
Definition command.c:3672
static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch)
Definition command.c:2541
static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name)
Definition command.c:3702
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:4728
static backslashResult exec_command_x(PsqlScanState scan_state, bool active_branch)
Definition command.c:3520
static backslashResult exec_command_if(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition command.c:2103
static char * pset_quoted_string(const char *str)
Definition command.c:5738
static backslashResult exec_command_elif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition command.c:2149
static bool param_is_newly_set(const char *old_val, const char *new_val)
Definition command.c:3892
static void ignore_slash_whole_line(PsqlScanState scan_state)
Definition command.c:3772
static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch)
Definition command.c:1672
static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf)
Definition command.c:2764
static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch)
Definition command.c:2458
static bool do_connect(enum trivalue reuse_previous_specification, char *dbname, char *user, char *host, char *port)
Definition command.c:3915
static bool lookup_object_oid(EditableObjectType obj_type, const char *desc, Oid *obj_oid)
Definition command.c:6193
static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:1558
static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:1019
static const char * pset_bool_string(bool val)
Definition command.c:5731
static int count_lines_in_buf(PQExpBuffer buf)
Definition command.c:6459
static bool echo_hidden_command(const char *query)
Definition command.c:6161
static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition command.c:3800
static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
Definition command.c:3579
bool do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
Definition command.c:5076
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:1987
static void printSSLInfo(void)
Definition command.c:4500
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, bool is_func)
Definition command.c:1442
static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:3232
static void ignore_slash_filepipe(PsqlScanState scan_state)
Definition command.c:3752
static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch)
Definition command.c:2875
static bool printPsetInfo(const char *param, printQueryOpt *popt)
Definition command.c:5449
static const char * _align2string(enum printFormat in)
Definition command.c:4990
static char * read_connect_arg(PsqlScanState scan_state)
Definition command.c:3632
static char * restrict_key
Definition command.c:200
static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch)
Definition command.c:2811
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:2617
static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition command.c:3364
static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:2062
static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:2330
static bool restricted
Definition command.c:199
static bool editFile(const char *fname, int lineno)
Definition command.c:4646
static backslashResult exec_command_sendpipeline(PsqlScanState scan_state, bool active_branch)
Definition command.c:2838
static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch)
Definition command.c:3160
static backslashResult exec_command_restrict(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:2782
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd, const char *pattern, bool show_verbose, bool show_system)
Definition command.c:1304
void UnsyncVariables(void)
Definition command.c:4624
static backslashResult exec_command_unrestrict(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:3192
static backslashResult exec_command_endpipeline(PsqlScanState scan_state, bool active_branch)
Definition command.c:3097
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:1603
static void wait_until_connected(PGconn *conn)
Definition command.c:4379
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition command.c:1346
static backslashResult exec_command_else(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition command.c:2225
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:5869
void SyncVariables(void)
Definition command.c:4569
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:3601
static backslashResult exec_command_parse(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:2507
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:2694
static void ignore_slash_options(PsqlScanState scan_state)
Definition command.c:3735
static backslashResult exec_command_flush(PsqlScanState scan_state, bool active_branch)
Definition command.c:1694
static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch)
Definition command.c:3116
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:4441
static backslashResult exec_command_write(PsqlScanState scan_state, bool active_branch, const char *cmd, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition command.c:3262
static backslashResult exec_command_syncpipeline(PsqlScanState scan_state, bool active_branch)
Definition command.c:3078
static void minimal_error_message(PGresult *res)
Definition command.c:6531
static backslashResult exec_command_sf_sv(PsqlScanState scan_state, bool active_branch, const char *cmd, bool is_func)
Definition command.c:2976
static bool is_branching_command(const char *cmd)
Definition command.c:3784
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:6489
static int strip_lineno_from_objdesc(char *obj)
Definition command.c:6401
static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch)
Definition command.c:1964
static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:3542
static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:2367
static backslashResult exec_command_getenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:1891
static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch)
Definition command.c:2750
EditableObjectType
Definition command.c:51
@ EditableFunction
Definition command.c:52
@ EditableView
Definition command.c:53
#define DEFAULT_SHELL
Definition command.c:5859
static backslashResult process_command_g_options(char *first_option, PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:1799
static void printGSSInfo(void)
Definition command.c:4528
static char * prompt_for_password(const char *username, bool *canceled)
Definition command.c:3864
static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition command.c:2928
@ 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:6136
bool listTSConfigs(const char *pattern, bool verbose)
Definition describe.c:5778
bool describeRoles(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:3788
bool listOpFamilyFunctions(const char *access_method_pattern, const char *family_pattern, bool verbose)
Definition describe.c:7359
bool listPublications(const char *pattern)
Definition describe.c:6491
bool listTSParsers(const char *pattern, bool verbose)
Definition describe.c:5394
bool listExtensionContents(const char *pattern)
Definition describe.c:6323
bool describeAggregates(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:79
bool listForeignDataWrappers(const char *pattern, bool verbose)
Definition describe.c:5985
bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
Definition describe.c:4349
bool describeSubscriptions(const char *pattern, bool verbose)
Definition describe.c:6889
bool describeRoleGrants(const char *pattern, bool showSystem)
Definition describe.c:4001
bool describeTypes(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:622
bool listOperatorFamilies(const char *access_method_pattern, const char *type_pattern, bool verbose)
Definition describe.c:7161
bool listForeignServers(const char *pattern, bool verbose)
Definition describe.c:6058
bool describeTableDetails(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:1449
bool listDomains(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:4625
bool listTSDictionaries(const char *pattern, bool verbose)
Definition describe.c:5646
bool listDbRoleSettings(const char *pattern, const char *pattern2)
Definition describe.c:3931
bool describeFunctions(const char *functypes, const char *func_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
Definition describe.c:289
bool listCollations(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:5150
bool listSchemas(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:5269
bool listExtensions(const char *pattern)
Definition describe.c:6267
bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
Definition describe.c:4082
bool listTSTemplates(const char *pattern, bool verbose)
Definition describe.c:5712
bool describeTablespaces(const char *pattern, bool verbose)
Definition describe.c:215
bool listCasts(const char *pattern, bool verbose)
Definition describe.c:5025
bool listOpFamilyOperators(const char *access_method_pattern, const char *family_pattern, bool verbose)
Definition describe.c:7251
bool describeOperators(const char *oper_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
Definition describe.c:778
bool listOperatorClasses(const char *access_method_pattern, const char *type_pattern, bool verbose)
Definition describe.c:7059
bool listForeignTables(const char *pattern, bool verbose)
Definition describe.c:6193
bool describeConfigurationParameters(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:4790
bool listEventTriggers(const char *pattern, bool verbose)
Definition describe.c:4861
bool listDefaultACLs(const char *pattern)
Definition describe.c:1173
bool listAllDbs(const char *pattern, bool verbose)
Definition describe.c:931
bool listConversions(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:4709
bool permissionsList(const char *pattern, bool showSystem)
Definition describe.c:1036
bool describeAccessMethods(const char *pattern, bool verbose)
Definition describe.c:150
bool listLargeObjects(bool verbose)
Definition describe.c:7450
bool listLanguages(const char *pattern, bool verbose, bool showSystem)
Definition describe.c:4548
bool describePublications(const char *pattern)
Definition describe.c:6620
bool listExtendedStats(const char *pattern, bool verbose)
Definition describe.c:4932
bool objectDescription(const char *pattern, bool showSystem)
Definition describe.c:1255
Datum arg
Definition elog.c:1323
#define _(x)
Definition elog.c:96
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:877
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:4068
char * PQresultVerboseErrorMessage(const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
Definition fe-exec.c:3466
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:1285
pg_usec_time_t PQgetCurrentTimeUSec(void)
Definition fe-misc.c:1379
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:53
char * pg_strdup(const char *in)
Definition fe_memutils.c:91
void pg_free(void *ptr)
void * pg_realloc(void *ptr, size_t size)
Definition fe_memutils.c:71
#define pg_realloc_array(pointer, type, count)
Definition fe_memutils.h:74
#define pg_malloc_array(type, count)
Definition fe_memutils.h:66
#define pg_malloc_object(type)
Definition fe_memutils.h:60
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
Definition print.c:3209
void printTableCleanup(printTableContent *const content)
Definition print.c:3390
void restore_sigpipe_trap(void)
Definition print.c:3065
const printTextFormat * get_line_style(const printTableOpt *opt)
Definition print.c:3893
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition print.c:3096
void refresh_utf8format(const printTableOpt *opt)
Definition print.c:3907
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition print.c:3297
const printTextFormat pg_asciiformat
Definition print.c:61
void ClosePager(FILE *pagerpipe)
Definition print.c:3178
const printTextFormat pg_asciiformat_old
Definition print.c:82
void disable_sigpipe_trap(void)
Definition print.c:3042
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition print.c:3654
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition print.c:3257
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 @175 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:251
@ 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:168
#define pg_log_error(...)
Definition logging.h:108
#define pg_log_error_hint(...)
Definition logging.h:114
#define PG_LOG_FLAG_TERSE
Definition logging.h:86
#define pg_log_info(...)
Definition logging.h:126
int MainLoop(FILE *source)
Definition mainloop.c:33
char * pstrdup(const char *in)
Definition mcxt.c:1910
void pfree(void *pointer)
Definition mcxt.c:1619
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 int server_version
Definition pg_dumpall.c:109
static char * filename
Definition pg_dumpall.c:120
static char * user
Definition pg_regress.c:121
static int port
Definition pg_regress.c:117
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define pg_encoding_to_char
Definition pg_wchar.h:483
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:105
int pg_strcasecmp(const char *s1, const char *s2)
void get_parent_directory(char *path)
Definition path.c:1085
void canonicalize_path_enc(char *path, int encoding)
Definition path.c:344
#define strerror
Definition port.h:274
#define snprintf
Definition port.h:261
#define printf(...)
Definition port.h:267
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:1369
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:33
@ 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:142
#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:257
void PsqlVarEnumError(const char *name, const char *value, const char *suggestions)
Definition variables.c:487
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:282
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:560
#define EINTR
Definition win32_port.h:378
#define SIGALRM
Definition win32_port.h:164
#define setenv(x, y, z)
Definition win32_port.h:559
#define ITIMER_REAL
Definition win32_port.h:180
int uid_t
Definition win32_port.h:251