2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2019, PostgreSQL Global Development Group
6 * src/bin/psql/startup.c
8 #include "postgres_fe.h"
17 #include "getopt_long.h"
25 #include "fe_utils/logging.h"
26 #include "fe_utils/print.h"
37 #define SYSPSQLRC "psqlrc"
38 #define PSQLRC ".psqlrc"
40 #define SYSPSQLRC "psqlrc"
41 #define PSQLRC "psqlrc.conf"
45 * Structures to pass information between the option parsing routine
46 * and the main function
55 typedef struct SimpleActionListCell
57 struct SimpleActionListCell *next;
60 } SimpleActionListCell;
62 typedef struct SimpleActionList
64 SimpleActionListCell *head;
65 SimpleActionListCell *tail;
79 SimpleActionList actions;
82 static void parse_psql_options(int argc, char *argv[],
83 struct adhoc_opts *options);
84 static void simple_action_list_append(SimpleActionList *list,
85 enum _actions action, const char *val);
86 static void process_psqlrc(char *argv0);
87 static void process_psqlrc_file(char *filename);
88 static void showVersion(void);
89 static void EstablishVariableSpace(void);
94 log_pre_callback(void)
96 if (pset.queryFout && pset.queryFout != stdout)
97 fflush(pset.queryFout);
101 log_locus_callback(const char **filename, uint64 *lineno)
105 *filename = pset.inputfile;
106 *lineno = pset.lineno;
121 main(int argc, char *argv[])
123 struct adhoc_opts options;
125 bool have_password = false;
129 pg_logging_init(argv[0]);
130 pg_logging_set_pre_callback(log_pre_callback);
131 pg_logging_set_locus_callback(log_locus_callback);
132 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql"));
136 if ((strcmp(argv[1], "-?") == 0) || (argc == 2 && (strcmp(argv[1], "--help") == 0)))
141 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
148 pset.progname = get_progname(argv[0]);
152 pset.encoding = PQenv2encoding();
153 pset.queryFout = stdout;
154 pset.queryFoutPipe = false;
155 pset.copyStream = NULL;
156 pset.last_error_result = NULL;
157 pset.cur_cmd_source = stdin;
158 pset.cur_cmd_interactive = false;
160 /* We rely on unmentioned fields of pset.popt to start out 0/false/NULL */
161 pset.popt.topt.format = PRINT_ALIGNED;
162 pset.popt.topt.border = 1;
163 pset.popt.topt.pager = 1;
164 pset.popt.topt.pager_min_lines = 0;
165 pset.popt.topt.start_table = true;
166 pset.popt.topt.stop_table = true;
167 pset.popt.topt.default_footer = true;
169 pset.popt.topt.csvFieldSep[0] = DEFAULT_CSV_FIELD_SEP;
170 pset.popt.topt.csvFieldSep[1] = '\0';
172 pset.popt.topt.unicode_border_linestyle = UNICODE_LINESTYLE_SINGLE;
173 pset.popt.topt.unicode_column_linestyle = UNICODE_LINESTYLE_SINGLE;
174 pset.popt.topt.unicode_header_linestyle = UNICODE_LINESTYLE_SINGLE;
176 refresh_utf8format(&(pset.popt.topt));
178 /* We must get COLUMNS here before readline() sets it */
179 pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
181 pset.notty = (!isatty(fileno(stdin)) || !isatty(fileno(stdout)));
183 pset.getPassword = TRI_DEFAULT;
185 EstablishVariableSpace();
187 /* Create variables showing psql version number */
188 SetVariable(pset.vars, "VERSION", PG_VERSION_STR);
189 SetVariable(pset.vars, "VERSION_NAME", PG_VERSION);
190 SetVariable(pset.vars, "VERSION_NUM", CppAsString2(PG_VERSION_NUM));
192 /* Initialize variables for last error */
193 SetVariable(pset.vars, "LAST_ERROR_MESSAGE", "");
194 SetVariable(pset.vars, "LAST_ERROR_SQLSTATE", "00000");
196 /* Default values for variables (that don't match the result of \unset) */
197 SetVariableBool(pset.vars, "AUTOCOMMIT");
198 SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1);
199 SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2);
200 SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
202 parse_psql_options(argc, argv, &options);
205 * If no action was specified and we're in non-interactive mode, treat it
206 * as if the user had specified "-f -". This lets single-transaction mode
209 if (options.actions.head == NULL && pset.notty)
210 simple_action_list_append(&options.actions, ACT_FILE, NULL);
212 /* Bail out if -1 was specified but will be ignored. */
213 if (options.single_txn && options.actions.head == NULL)
215 pg_log_fatal("-1 can only be used in non-interactive mode");
219 if (!pset.popt.topt.fieldSep.separator &&
220 !pset.popt.topt.fieldSep.separator_zero)
222 pset.popt.topt.fieldSep.separator = pg_strdup(DEFAULT_FIELD_SEP);
223 pset.popt.topt.fieldSep.separator_zero = false;
225 if (!pset.popt.topt.recordSep.separator &&
226 !pset.popt.topt.recordSep.separator_zero)
228 pset.popt.topt.recordSep.separator = pg_strdup(DEFAULT_RECORD_SEP);
229 pset.popt.topt.recordSep.separator_zero = false;
232 if (pset.getPassword == TRI_YES)
235 * We can't be sure yet of the username that will be used, so don't
236 * offer a potentially wrong one. Typical uses of this option are
237 * noninteractive anyway.
239 simple_prompt("Password: ", password, sizeof(password), false);
240 have_password = true;
243 /* loop until we have a password if requested by backend */
246 #define PARAMS_ARRAY_SIZE 8
247 const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
248 const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
250 keywords[0] = "host";
251 values[0] = options.host;
252 keywords[1] = "port";
253 values[1] = options.port;
254 keywords[2] = "user";
255 values[2] = options.username;
256 keywords[3] = "password";
257 values[3] = have_password ? password : NULL;
258 keywords[4] = "dbname"; /* see do_connect() */
259 values[4] = (options.list_dbs && options.dbname == NULL) ?
260 "postgres" : options.dbname;
261 keywords[5] = "fallback_application_name";
262 values[5] = pset.progname;
263 keywords[6] = "client_encoding";
264 values[6] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto";
269 pset.db = PQconnectdbParams(keywords, values, true);
273 if (PQstatus(pset.db) == CONNECTION_BAD &&
274 PQconnectionNeedsPassword(pset.db) &&
276 pset.getPassword != TRI_NO)
279 * Before closing the old PGconn, extract the user name that was
280 * actually connected with --- it might've come out of a URI or
281 * connstring "database name" rather than options.username.
283 const char *realusername = PQuser(pset.db);
284 char *password_prompt;
286 if (realusername && realusername[0])
287 password_prompt = psprintf(_("Password for user %s: "),
290 password_prompt = pg_strdup(_("Password: "));
293 simple_prompt(password_prompt, password, sizeof(password), false);
294 free(password_prompt);
295 have_password = true;
300 if (PQstatus(pset.db) == CONNECTION_BAD)
302 pg_log_error("could not connect to server: %s", PQerrorMessage(pset.db));
307 setup_cancel_handler();
309 PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);
313 if (options.list_dbs)
317 if (!options.no_psqlrc)
318 process_psqlrc(argv[0]);
320 success = listAllDbs(NULL, false);
322 exit(success ? EXIT_SUCCESS : EXIT_FAILURE);
325 if (options.logfilename)
327 pset.logfile = fopen(options.logfilename, "a");
330 pg_log_fatal("could not open log file \"%s\": %m",
331 options.logfilename);
336 if (!options.no_psqlrc)
337 process_psqlrc(argv[0]);
340 * If any actions were given by user, process them in the order in which
341 * they were specified. Note single_txn is only effective in this mode.
343 if (options.actions.head != NULL)
346 SimpleActionListCell *cell;
348 successResult = EXIT_SUCCESS; /* silence compiler */
350 if (options.single_txn)
352 if ((res = PSQLexec("BEGIN")) == NULL)
354 if (pset.on_error_stop)
356 successResult = EXIT_USER;
364 for (cell = options.actions.head; cell; cell = cell->next)
366 if (cell->action == ACT_SINGLE_QUERY)
368 pg_logging_config(PG_LOG_FLAG_TERSE);
370 if (pset.echo == PSQL_ECHO_ALL)
373 successResult = SendQuery(cell->val)
374 ? EXIT_SUCCESS : EXIT_FAILURE;
376 else if (cell->action == ACT_SINGLE_SLASH)
378 PsqlScanState scan_state;
379 ConditionalStack cond_stack;
381 pg_logging_config(PG_LOG_FLAG_TERSE);
383 if (pset.echo == PSQL_ECHO_ALL)
386 scan_state = psql_scan_create(&psqlscan_callbacks);
387 psql_scan_setup(scan_state,
388 cell->val, strlen(cell->val),
389 pset.encoding, standard_strings());
390 cond_stack = conditional_stack_create();
391 psql_scan_set_passthrough(scan_state, (void *) cond_stack);
393 successResult = HandleSlashCmds(scan_state,
396 NULL) != PSQL_CMD_ERROR
397 ? EXIT_SUCCESS : EXIT_FAILURE;
399 psql_scan_destroy(scan_state);
400 conditional_stack_destroy(cond_stack);
402 else if (cell->action == ACT_FILE)
404 successResult = process_file(cell->val, false);
408 /* should never come here */
412 if (successResult != EXIT_SUCCESS && pset.on_error_stop)
416 if (options.single_txn)
418 if ((res = PSQLexec("COMMIT")) == NULL)
420 if (pset.on_error_stop)
422 successResult = EXIT_USER;
435 * or otherwise enter interactive main loop
439 connection_warnings(true);
441 printf(_("Type \"help\" for help.\n\n"));
442 initializeInput(options.no_readline ? 0 : 1);
443 successResult = MainLoop(stdin);
448 fclose(pset.logfile);
452 return successResult;
457 * Parse command line options
461 parse_psql_options(int argc, char *argv[], struct adhoc_opts *options)
463 static struct option long_options[] =
465 {"echo-all", no_argument, NULL, 'a'},
466 {"no-align", no_argument, NULL, 'A'},
467 {"command", required_argument, NULL, 'c'},
468 {"dbname", required_argument, NULL, 'd'},
469 {"echo-queries", no_argument, NULL, 'e'},
470 {"echo-errors", no_argument, NULL, 'b'},
471 {"echo-hidden", no_argument, NULL, 'E'},
472 {"file", required_argument, NULL, 'f'},
473 {"field-separator", required_argument, NULL, 'F'},
474 {"field-separator-zero", no_argument, NULL, 'z'},
475 {"host", required_argument, NULL, 'h'},
476 {"html", no_argument, NULL, 'H'},
477 {"list", no_argument, NULL, 'l'},
478 {"log-file", required_argument, NULL, 'L'},
479 {"no-readline", no_argument, NULL, 'n'},
480 {"single-transaction", no_argument, NULL, '1'},
481 {"output", required_argument, NULL, 'o'},
482 {"port", required_argument, NULL, 'p'},
483 {"pset", required_argument, NULL, 'P'},
484 {"quiet", no_argument, NULL, 'q'},
485 {"record-separator", required_argument, NULL, 'R'},
486 {"record-separator-zero", no_argument, NULL, '0'},
487 {"single-step", no_argument, NULL, 's'},
488 {"single-line", no_argument, NULL, 'S'},
489 {"tuples-only", no_argument, NULL, 't'},
490 {"table-attr", required_argument, NULL, 'T'},
491 {"username", required_argument, NULL, 'U'},
492 {"set", required_argument, NULL, 'v'},
493 {"variable", required_argument, NULL, 'v'},
494 {"version", no_argument, NULL, 'V'},
495 {"no-password", no_argument, NULL, 'w'},
496 {"password", no_argument, NULL, 'W'},
497 {"expanded", no_argument, NULL, 'x'},
498 {"no-psqlrc", no_argument, NULL, 'X'},
499 {"help", optional_argument, NULL, 1},
500 {"csv", no_argument, NULL, 2},
507 memset(options, 0, sizeof *options);
509 while ((c = getopt_long(argc, argv, "aAbc:d:eEf:F:h:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01",
510 long_options, &optindex)) != -1)
515 SetVariable(pset.vars, "ECHO", "all");
518 pset.popt.topt.format = PRINT_UNALIGNED;
521 SetVariable(pset.vars, "ECHO", "errors");
524 if (optarg[0] == '\\')
525 simple_action_list_append(&options->actions,
529 simple_action_list_append(&options->actions,
534 options->dbname = pg_strdup(optarg);
537 SetVariable(pset.vars, "ECHO", "queries");
540 SetVariableBool(pset.vars, "ECHO_HIDDEN");
543 simple_action_list_append(&options->actions,
548 pset.popt.topt.fieldSep.separator = pg_strdup(optarg);
549 pset.popt.topt.fieldSep.separator_zero = false;
552 options->host = pg_strdup(optarg);
555 pset.popt.topt.format = PRINT_HTML;
558 options->list_dbs = true;
561 options->logfilename = pg_strdup(optarg);
564 options->no_readline = true;
567 if (!setQFout(optarg))
571 options->port = pg_strdup(optarg);
579 value = pg_strdup(optarg);
580 equal_loc = strchr(value, '=');
582 result = do_pset(value, NULL, &pset.popt, true);
586 result = do_pset(value, equal_loc + 1, &pset.popt, true);
591 pg_log_fatal("could not set printing parameter \"%s\"", value);
599 SetVariableBool(pset.vars, "QUIET");
602 pset.popt.topt.recordSep.separator = pg_strdup(optarg);
603 pset.popt.topt.recordSep.separator_zero = false;
606 SetVariableBool(pset.vars, "SINGLESTEP");
609 SetVariableBool(pset.vars, "SINGLELINE");
612 pset.popt.topt.tuples_only = true;
615 pset.popt.topt.tableAttr = pg_strdup(optarg);
618 options->username = pg_strdup(optarg);
625 value = pg_strdup(optarg);
626 equal_loc = strchr(value, '=');
629 if (!DeleteVariable(pset.vars, value))
630 exit(EXIT_FAILURE); /* error already printed */
635 if (!SetVariable(pset.vars, value, equal_loc + 1))
636 exit(EXIT_FAILURE); /* error already printed */
646 pset.getPassword = TRI_NO;
649 pset.getPassword = TRI_YES;
652 pset.popt.topt.expanded = true;
655 options->no_psqlrc = true;
658 pset.popt.topt.fieldSep.separator_zero = true;
661 pset.popt.topt.recordSep.separator_zero = true;
664 options->single_txn = true;
667 /* Actual help option given */
668 if (strcmp(argv[optind - 1], "-?") == 0)
673 /* unknown option reported by getopt */
679 if (!optarg || strcmp(optarg, "options") == 0)
681 else if (optarg && strcmp(optarg, "commands") == 0)
683 else if (optarg && strcmp(optarg, "variables") == 0)
684 helpVariables(NOPAGER);
692 pset.popt.topt.format = PRINT_CSV;
696 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
704 * if we still have arguments, use it as the database name and username
706 while (argc - optind >= 1)
708 if (!options->dbname)
709 options->dbname = argv[optind];
710 else if (!options->username)
711 options->username = argv[optind];
712 else if (!pset.quiet)
713 pg_log_warning("extra command-line argument \"%s\" ignored",
722 * Append a new item to the end of the SimpleActionList.
723 * Note that "val" is copied if it's not NULL.
726 simple_action_list_append(SimpleActionList *list,
727 enum _actions action, const char *val)
729 SimpleActionListCell *cell;
731 cell = (SimpleActionListCell *) pg_malloc(sizeof(SimpleActionListCell));
734 cell->action = action;
736 cell->val = pg_strdup(val);
741 list->tail->next = cell;
749 * Load .psqlrc file, if found.
752 process_psqlrc(char *argv0)
754 char home[MAXPGPATH];
755 char rc_file[MAXPGPATH];
756 char my_exec_path[MAXPGPATH];
757 char etc_path[MAXPGPATH];
758 char *envrc = getenv("PSQLRC");
760 if (find_my_exec(argv0, my_exec_path) < 0)
762 pg_log_fatal("could not find own program executable");
766 get_etc_path(my_exec_path, etc_path);
768 snprintf(rc_file, MAXPGPATH, "%s/%s", etc_path, SYSPSQLRC);
769 process_psqlrc_file(rc_file);
771 if (envrc != NULL && strlen(envrc) > 0)
773 /* might need to free() this */
774 char *envrc_alloc = pstrdup(envrc);
776 expand_tilde(&envrc_alloc);
777 process_psqlrc_file(envrc_alloc);
779 else if (get_home_path(home))
781 snprintf(rc_file, MAXPGPATH, "%s/%s", home, PSQLRC);
782 process_psqlrc_file(rc_file);
789 process_psqlrc_file(char *filename)
794 #if defined(WIN32) && (!defined(__MINGW32__))
798 psqlrc_minor = psprintf("%s-%s", filename, PG_VERSION);
799 psqlrc_major = psprintf("%s-%s", filename, PG_MAJORVERSION);
801 /* check for minor version first, then major, then no version */
802 if (access(psqlrc_minor, R_OK) == 0)
803 (void) process_file(psqlrc_minor, false);
804 else if (access(psqlrc_major, R_OK) == 0)
805 (void) process_file(psqlrc_major, false);
806 else if (access(filename, R_OK) == 0)
807 (void) process_file(filename, false);
817 * This output format is intended to match GNU standards.
822 puts("psql (PostgreSQL) " PG_VERSION);
828 * Substitute hooks and assign hooks for psql variables.
830 * This isn't an amazingly good place for them, but neither is anywhere else.
832 * By policy, every special variable that controls any psql behavior should
833 * have one or both hooks, even if they're just no-ops. This ensures that
834 * the variable will remain present in variables.c's list even when unset,
835 * which ensures that it's known to tab completion.
839 bool_substitute_hook(char *newval)
843 /* "\unset FOO" becomes "\set FOO off" */
844 newval = pg_strdup("off");
846 else if (newval[0] == '\0')
848 /* "\set FOO" becomes "\set FOO on" */
850 newval = pg_strdup("on");
856 autocommit_hook(const char *newval)
858 return ParseVariableBool(newval, "AUTOCOMMIT", &pset.autocommit);
862 on_error_stop_hook(const char *newval)
864 return ParseVariableBool(newval, "ON_ERROR_STOP", &pset.on_error_stop);
868 quiet_hook(const char *newval)
870 return ParseVariableBool(newval, "QUIET", &pset.quiet);
874 singleline_hook(const char *newval)
876 return ParseVariableBool(newval, "SINGLELINE", &pset.singleline);
880 singlestep_hook(const char *newval)
882 return ParseVariableBool(newval, "SINGLESTEP", &pset.singlestep);
886 fetch_count_substitute_hook(char *newval)
889 newval = pg_strdup("0");
894 fetch_count_hook(const char *newval)
896 return ParseVariableNum(newval, "FETCH_COUNT", &pset.fetch_count);
900 histfile_hook(const char *newval)
903 * Someday we might try to validate the filename, but for now, this is
904 * just a placeholder to ensure HISTFILE is known to tab completion.
910 histsize_substitute_hook(char *newval)
913 newval = pg_strdup("500");
918 histsize_hook(const char *newval)
920 return ParseVariableNum(newval, "HISTSIZE", &pset.histsize);
924 ignoreeof_substitute_hook(char *newval)
929 * This tries to mimic the behavior of bash, to wit "If set, the value is
930 * the number of consecutive EOF characters which must be typed as the
931 * first characters on an input line before bash exits. If the variable
932 * exists but does not have a numeric value, or has no value, the default
933 * value is 10. If it does not exist, EOF signifies the end of input to
934 * the shell." Unlike bash, however, we insist on the stored value
935 * actually being a valid integer.
938 newval = pg_strdup("0");
939 else if (!ParseVariableNum(newval, NULL, &dummy))
940 newval = pg_strdup("10");
945 ignoreeof_hook(const char *newval)
947 return ParseVariableNum(newval, "IGNOREEOF", &pset.ignoreeof);
951 echo_substitute_hook(char *newval)
954 newval = pg_strdup("none");
959 echo_hook(const char *newval)
961 Assert(newval != NULL); /* else substitute hook messed up */
962 if (pg_strcasecmp(newval, "queries") == 0)
963 pset.echo = PSQL_ECHO_QUERIES;
964 else if (pg_strcasecmp(newval, "errors") == 0)
965 pset.echo = PSQL_ECHO_ERRORS;
966 else if (pg_strcasecmp(newval, "all") == 0)
967 pset.echo = PSQL_ECHO_ALL;
968 else if (pg_strcasecmp(newval, "none") == 0)
969 pset.echo = PSQL_ECHO_NONE;
972 PsqlVarEnumError("ECHO", newval, "none, errors, queries, all");
979 echo_hidden_hook(const char *newval)
981 Assert(newval != NULL); /* else substitute hook messed up */
982 if (pg_strcasecmp(newval, "noexec") == 0)
983 pset.echo_hidden = PSQL_ECHO_HIDDEN_NOEXEC;
988 if (ParseVariableBool(newval, NULL, &on_off))
989 pset.echo_hidden = on_off ? PSQL_ECHO_HIDDEN_ON : PSQL_ECHO_HIDDEN_OFF;
992 PsqlVarEnumError("ECHO_HIDDEN", newval, "on, off, noexec");
1000 on_error_rollback_hook(const char *newval)
1002 Assert(newval != NULL); /* else substitute hook messed up */
1003 if (pg_strcasecmp(newval, "interactive") == 0)
1004 pset.on_error_rollback = PSQL_ERROR_ROLLBACK_INTERACTIVE;
1009 if (ParseVariableBool(newval, NULL, &on_off))
1010 pset.on_error_rollback = on_off ? PSQL_ERROR_ROLLBACK_ON : PSQL_ERROR_ROLLBACK_OFF;
1013 PsqlVarEnumError("ON_ERROR_ROLLBACK", newval, "on, off, interactive");
1021 comp_keyword_case_substitute_hook(char *newval)
1024 newval = pg_strdup("preserve-upper");
1029 comp_keyword_case_hook(const char *newval)
1031 Assert(newval != NULL); /* else substitute hook messed up */
1032 if (pg_strcasecmp(newval, "preserve-upper") == 0)
1033 pset.comp_case = PSQL_COMP_CASE_PRESERVE_UPPER;
1034 else if (pg_strcasecmp(newval, "preserve-lower") == 0)
1035 pset.comp_case = PSQL_COMP_CASE_PRESERVE_LOWER;
1036 else if (pg_strcasecmp(newval, "upper") == 0)
1037 pset.comp_case = PSQL_COMP_CASE_UPPER;
1038 else if (pg_strcasecmp(newval, "lower") == 0)
1039 pset.comp_case = PSQL_COMP_CASE_LOWER;
1042 PsqlVarEnumError("COMP_KEYWORD_CASE", newval,
1043 "lower, upper, preserve-lower, preserve-upper");
1050 histcontrol_substitute_hook(char *newval)
1053 newval = pg_strdup("none");
1058 histcontrol_hook(const char *newval)
1060 Assert(newval != NULL); /* else substitute hook messed up */
1061 if (pg_strcasecmp(newval, "ignorespace") == 0)
1062 pset.histcontrol = hctl_ignorespace;
1063 else if (pg_strcasecmp(newval, "ignoredups") == 0)
1064 pset.histcontrol = hctl_ignoredups;
1065 else if (pg_strcasecmp(newval, "ignoreboth") == 0)
1066 pset.histcontrol = hctl_ignoreboth;
1067 else if (pg_strcasecmp(newval, "none") == 0)
1068 pset.histcontrol = hctl_none;
1071 PsqlVarEnumError("HISTCONTROL", newval,
1072 "none, ignorespace, ignoredups, ignoreboth");
1079 prompt1_hook(const char *newval)
1081 pset.prompt1 = newval ? newval : "";
1086 prompt2_hook(const char *newval)
1088 pset.prompt2 = newval ? newval : "";
1093 prompt3_hook(const char *newval)
1095 pset.prompt3 = newval ? newval : "";
1100 verbosity_substitute_hook(char *newval)
1103 newval = pg_strdup("default");
1108 verbosity_hook(const char *newval)
1110 Assert(newval != NULL); /* else substitute hook messed up */
1111 if (pg_strcasecmp(newval, "default") == 0)
1112 pset.verbosity = PQERRORS_DEFAULT;
1113 else if (pg_strcasecmp(newval, "verbose") == 0)
1114 pset.verbosity = PQERRORS_VERBOSE;
1115 else if (pg_strcasecmp(newval, "terse") == 0)
1116 pset.verbosity = PQERRORS_TERSE;
1117 else if (pg_strcasecmp(newval, "sqlstate") == 0)
1118 pset.verbosity = PQERRORS_SQLSTATE;
1121 PsqlVarEnumError("VERBOSITY", newval, "default, verbose, terse, sqlstate");
1126 PQsetErrorVerbosity(pset.db, pset.verbosity);
1131 show_context_substitute_hook(char *newval)
1134 newval = pg_strdup("errors");
1139 show_context_hook(const char *newval)
1141 Assert(newval != NULL); /* else substitute hook messed up */
1142 if (pg_strcasecmp(newval, "never") == 0)
1143 pset.show_context = PQSHOW_CONTEXT_NEVER;
1144 else if (pg_strcasecmp(newval, "errors") == 0)
1145 pset.show_context = PQSHOW_CONTEXT_ERRORS;
1146 else if (pg_strcasecmp(newval, "always") == 0)
1147 pset.show_context = PQSHOW_CONTEXT_ALWAYS;
1150 PsqlVarEnumError("SHOW_CONTEXT", newval, "never, errors, always");
1155 PQsetErrorContextVisibility(pset.db, pset.show_context);
1160 hide_tableam_hook(const char *newval)
1162 return ParseVariableBool(newval, "HIDE_TABLEAM", &pset.hide_tableam);
1166 EstablishVariableSpace(void)
1168 pset.vars = CreateVariableSpace();
1170 SetVariableHooks(pset.vars, "AUTOCOMMIT",
1171 bool_substitute_hook,
1173 SetVariableHooks(pset.vars, "ON_ERROR_STOP",
1174 bool_substitute_hook,
1175 on_error_stop_hook);
1176 SetVariableHooks(pset.vars, "QUIET",
1177 bool_substitute_hook,
1179 SetVariableHooks(pset.vars, "SINGLELINE",
1180 bool_substitute_hook,
1182 SetVariableHooks(pset.vars, "SINGLESTEP",
1183 bool_substitute_hook,
1185 SetVariableHooks(pset.vars, "FETCH_COUNT",
1186 fetch_count_substitute_hook,
1188 SetVariableHooks(pset.vars, "HISTFILE",
1191 SetVariableHooks(pset.vars, "HISTSIZE",
1192 histsize_substitute_hook,
1194 SetVariableHooks(pset.vars, "IGNOREEOF",
1195 ignoreeof_substitute_hook,
1197 SetVariableHooks(pset.vars, "ECHO",
1198 echo_substitute_hook,
1200 SetVariableHooks(pset.vars, "ECHO_HIDDEN",
1201 bool_substitute_hook,
1203 SetVariableHooks(pset.vars, "ON_ERROR_ROLLBACK",
1204 bool_substitute_hook,
1205 on_error_rollback_hook);
1206 SetVariableHooks(pset.vars, "COMP_KEYWORD_CASE",
1207 comp_keyword_case_substitute_hook,
1208 comp_keyword_case_hook);
1209 SetVariableHooks(pset.vars, "HISTCONTROL",
1210 histcontrol_substitute_hook,
1212 SetVariableHooks(pset.vars, "PROMPT1",
1215 SetVariableHooks(pset.vars, "PROMPT2",
1218 SetVariableHooks(pset.vars, "PROMPT3",
1221 SetVariableHooks(pset.vars, "VERBOSITY",
1222 verbosity_substitute_hook,
1224 SetVariableHooks(pset.vars, "SHOW_CONTEXT",
1225 show_context_substitute_hook,
1227 SetVariableHooks(pset.vars, "HIDE_TABLEAM",
1228 bool_substitute_hook,