2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2025, PostgreSQL Global Development Group
6 * src/bin/psql/startup.c
35 #define SYSPSQLRC "psqlrc"
36 #define PSQLRC ".psqlrc"
38#define SYSPSQLRC "psqlrc"
39#define PSQLRC "psqlrc.conf"
43 * Structures to pass information between the option parsing routine
44 * and the main function
140 if ((strcmp(argv[1],
"-?") == 0) || (argc == 2 && (strcmp(argv[1],
"--help") == 0)))
145 if (strcmp(argv[1],
"--version") == 0 || strcmp(argv[1],
"-V") == 0)
165 /* We rely on unmentioned fields of pset.popt to start out 0/false/NULL */
183 /* We must get COLUMNS here before readline() sets it */
192 /* Create variables showing psql version number */
197 /* Initialize variables for last error */
201 /* Default values for variables (that don't match the result of \unset) */
208 /* Initialize pipeline variables */
216 * If no action was specified and we're in non-interactive mode, treat it
217 * as if the user had specified "-f -". This lets single-transaction mode
223 /* Bail out if -1 was specified but will be ignored. */
225 pg_fatal(
"-1 can only be used in non-interactive mode");
243 * We can't be sure yet of the username that will be used, so don't
244 * offer a potentially wrong one. Typical uses of this option are
245 * noninteractive anyway. (Note: since we've not yet set up our
246 * cancel handler, there's no need to use simple_prompt_extended.)
251 /* loop until we have a password if requested by backend */
254#define PARAMS_ARRAY_SIZE 8
266 keywords[4] =
"dbname";
/* see do_connect() */
269 keywords[5] =
"fallback_application_name";
272 values[6] = (
pset.
notty || getenv(
"PGCLIENTENCODING")) ? NULL :
"auto";
287 * Before closing the old PGconn, extract the user name that was
288 * actually connected with --- it might've come out of a URI or
289 * connstring "database name" rather than options.username.
292 char *password_prompt;
294 if (realusername && realusername[0])
295 password_prompt =
psprintf(
_(
"Password for user %s: "),
302 free(password_prompt);
319 * do_watch() needs signal handlers installed (otherwise sigwait() will
320 * filter them out on some platforms), but doesn't need them to do
321 * anything, and they shouldn't ever run (unless perhaps a stray SIGALRM
322 * arrives due to a race when do_watch() cancels an itimer).
348 pg_fatal(
"could not open log file \"%s\": %m",
356 * If any actions were given by user, process them in the order in which
357 * they were specified. Note single_txn is only effective in this mode.
359 if (
options.actions.head != NULL)
368 if ((res =
PSQLexec(
"BEGIN")) == NULL)
380 for (cell =
options.actions.head; cell; cell = cell->
next)
404 cell->
val, strlen(cell->
val),
424 /* should never come here */
435 * Rollback the contents of the single transaction if the caller
436 * has set ON_ERROR_STOP and one of the steps has failed. This
437 * check needs to match the one done a couple of lines above.
440 "ROLLBACK" :
"COMMIT");
458 * or otherwise enter interactive main loop
465 printf(
_(
"Type \"help\" for help.\n\n"));
479 return successResult;
484 * Parse command line options
490 static struct option long_options[] =
536 while ((
c =
getopt_long(argc, argv,
"aAbc:d:eEf:F:h:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01",
537 long_options, &optindex)) != -1)
607 equal_loc = strchr(
value,
'=');
650 equal_loc = strchr(
value,
'=');
692 strcmp(argv[
optind - 1],
"-?") == 0)
694 /* actual help option given */
700 /* getopt error (unknown option or missing argument) */
723 /* getopt_long already emitted a complaint */
731 * if we still have arguments, use it as the database name and username
733 while (argc -
optind >= 1)
749 * Append a new item to the end of the SimpleActionList.
750 * Note that "val" is copied if it's not NULL.
768 list->tail->next = cell;
776 * Load .psqlrc file, if found.
785 char *envrc = getenv(
"PSQLRC");
788 pg_fatal(
"could not find own program executable");
795 if (envrc != NULL && strlen(envrc) > 0)
797 /* might need to free() this */
798 char *envrc_alloc =
pstrdup(envrc);
818#if defined(WIN32) && (!defined(__MINGW32__))
825 /* check for minor version first, then major, then no version */
826 if (
access(psqlrc_minor, R_OK) == 0)
828 else if (
access(psqlrc_major, R_OK) == 0)
841 * This output format is intended to match GNU standards.
846 puts(
"psql (PostgreSQL) " PG_VERSION);
852 * Substitute hooks and assign hooks for psql variables.
854 * This isn't an amazingly good place for them, but neither is anywhere else.
856 * By policy, every special variable that controls any psql behavior should
857 * have one or both hooks, even if they're just no-ops. This ensures that
858 * the variable will remain present in variables.c's list even when unset,
859 * which ensures that it's known to tab completion.
867 /* "\unset FOO" becomes "\set FOO off" */
870 else if (
newval[0] ==
'0円')
872 /* "\set FOO" becomes "\set FOO on" */
927 * Someday we might try to validate the filename, but for now, this is
928 * just a placeholder to ensure HISTFILE is known to tab completion.
968 * This tries to mimic the behavior of bash, to wit "If set, the value is
969 * the number of consecutive EOF characters which must be typed as the
970 * first characters on an input line before bash exits. If the variable
971 * exists but does not have a numeric value, or has no value, the default
972 * value is 10. If it does not exist, EOF signifies the end of input to
973 * the shell." Unlike bash, however, we insist on the stored value
974 * actually being a valid integer.
1000 Assert(
newval != NULL);
/* else substitute hook messed up */
1020 Assert(
newval != NULL);
/* else substitute hook messed up */
1041 Assert(
newval != NULL);
/* else substitute hook messed up */
1070 Assert(
newval != NULL);
/* else substitute hook messed up */
1082 "lower, upper, preserve-lower, preserve-upper");
1099 Assert(
newval != NULL);
/* else substitute hook messed up */
1111 "none, ignorespace, ignoredups, ignoreboth");
1149 Assert(
newval != NULL);
/* else substitute hook messed up */
1186 Assert(
newval != NULL);
/* else substitute hook messed up */
void expand_tilde(char **filename)
PGresult * PSQLexec(const char *query)
void psql_setup_cancel_handler(void)
void NoticeProcessor(void *arg, const char *message)
bool standard_strings(void)
bool setQFout(const char *fname)
bool SendQuery(const char *query)
static char * verbosity_substitute_hook(char *newval)
static bool show_context_hook(const char *newval)
int main(int argc, char *argv[])
static bool hide_tableam_hook(const char *newval)
static bool quiet_hook(const char *newval)
static bool singleline_hook(const char *newval)
static bool prompt2_hook(const char *newval)
static bool comp_keyword_case_hook(const char *newval)
static bool histcontrol_hook(const char *newval)
static bool prompt1_hook(const char *newval)
static bool verbosity_hook(const char *newval)
static void empty_signal_handler(SIGNAL_ARGS)
static char * ignoreeof_substitute_hook(char *newval)
static bool show_all_results_hook(const char *newval)
struct SimpleActionListCell SimpleActionListCell
static bool fetch_count_hook(const char *newval)
static void process_psqlrc(char *argv0)
static char * fetch_count_substitute_hook(char *newval)
static void EstablishVariableSpace(void)
static bool histsize_hook(const char *newval)
static void log_pre_callback(void)
struct SimpleActionList SimpleActionList
static char * echo_substitute_hook(char *newval)
static char * watch_interval_substitute_hook(char *newval)
static bool hide_compression_hook(const char *newval)
static char * bool_substitute_hook(char *newval)
#define PARAMS_ARRAY_SIZE
static void log_locus_callback(const char **filename, uint64 *lineno)
static bool singlestep_hook(const char *newval)
static bool histfile_hook(const char *newval)
static bool prompt3_hook(const char *newval)
static bool on_error_rollback_hook(const char *newval)
static char * histsize_substitute_hook(char *newval)
static bool on_error_stop_hook(const char *newval)
static bool autocommit_hook(const char *newval)
static char * show_context_substitute_hook(char *newval)
static bool watch_interval_hook(const char *newval)
static bool ignoreeof_hook(const char *newval)
static bool echo_hidden_hook(const char *newval)
static void process_psqlrc_file(char *filename)
static bool echo_hook(const char *newval)
static void simple_action_list_append(SimpleActionList *list, enum _actions action, const char *val)
static void parse_psql_options(int argc, char *argv[], struct adhoc_opts *options)
static void showVersion(void)
static char * histcontrol_substitute_hook(char *newval)
static char * comp_keyword_case_substitute_hook(char *newval)
static Datum values[MAXATTR]
#define PG_TEXTDOMAIN(domain)
bool do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
backslashResult HandleSlashCmds(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
void connection_warnings(bool in_startup)
int find_my_exec(const char *argv0, char *retpath)
void set_pglocale_pgservice(const char *argv0, const char *app)
ConditionalStack conditional_stack_create(void)
void conditional_stack_destroy(ConditionalStack cstack)
bool listAllDbs(const char *pattern, bool verbose)
int PQconnectionNeedsPassword(const PGconn *conn)
ConnStatusType PQstatus(const PGconn *conn)
void PQfinish(PGconn *conn)
PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
char * PQuser(const PGconn *conn)
PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
char * PQerrorMessage(const PGconn *conn)
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
char * pg_strdup(const char *in)
#define pg_malloc_array(type, count)
#define pg_malloc_object(type)
void refresh_utf8format(const printTableOpt *opt)
void setDecimalLocale(void)
@ UNICODE_LINESTYLE_SINGLE
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
#define required_argument
#define optional_argument
char my_exec_path[MAXPGPATH]
Assert(PointerIsAligned(start, uint64))
void helpVariables(unsigned short int pager)
void slashUsage(unsigned short int pager)
static const JsonPathKeyword keywords[]
void pg_logging_init(const char *argv0)
void pg_logging_set_locus_callback(void(*cb)(const char **filename, uint64 *lineno))
void pg_logging_config(int new_flags)
void pg_logging_set_pre_callback(void(*cb)(void))
#define pg_log_error(...)
#define pg_log_error_hint(...)
#define PG_LOG_FLAG_TERSE
const PsqlScanCallbacks psqlscan_callbacks
int MainLoop(FILE *source)
char * pstrdup(const char *in)
PGDLLIMPORT char * optarg
static void process_file(const char *filename, int weight)
#define pg_log_warning(...)
bool get_home_path(char *ret_path)
int pg_strcasecmp(const char *s1, const char *s2)
void get_etc_path(const char *my_exec_path, char *ret_path)
const char * get_progname(const char *argv0)
char * psprintf(const char *fmt,...)
void psql_scan_destroy(PsqlScanState state)
PsqlScanState psql_scan_create(const PsqlScanCallbacks *callbacks)
void psql_scan_set_passthrough(PsqlScanState state, void *passthrough)
void psql_scan_setup(PsqlScanState state, const char *line, int line_len, int encoding, bool std_strings)
@ PSQL_ERROR_ROLLBACK_INTERACTIVE
@ PSQL_ERROR_ROLLBACK_OFF
#define DEFAULT_RECORD_SEP
#define DEFAULT_WATCH_INTERVAL_MAX
#define DEFAULT_FIELD_SEP
@ PSQL_ECHO_HIDDEN_NOEXEC
#define DEFAULT_WATCH_INTERVAL
@ PSQL_COMP_CASE_PRESERVE_LOWER
@ PSQL_COMP_CASE_PRESERVE_UPPER
#define DEFAULT_CSV_FIELD_SEP
char * simple_prompt(const char *prompt, bool echo)
struct SimpleActionListCell * next
SimpleActionListCell * head
SimpleActionListCell * tail
PSQL_ERROR_ROLLBACK on_error_rollback
PGresult * last_error_result
enum trivalue getPassword
PGContextVisibility show_context
PSQL_ECHO_HIDDEN echo_hidden
unsigned short int expanded
unicode_linestyle unicode_border_linestyle
struct separator fieldSep
struct separator recordSep
unsigned short int border
unicode_linestyle unicode_header_linestyle
unicode_linestyle unicode_column_linestyle
static void usage(const char *progname)
bool DeleteVariable(VariableSpace space, const char *name)
void SetVariableHooks(VariableSpace space, const char *name, VariableSubstituteHook shook, VariableAssignHook ahook)
void PsqlVarEnumError(const char *name, const char *value, const char *suggestions)
bool ParseVariableBool(const char *value, const char *name, bool *result)
bool ParseVariableDouble(const char *value, const char *name, double *result, double min, double max)
bool SetVariableBool(VariableSpace space, const char *name)
bool ParseVariableNum(const char *value, const char *name, int *result)
bool SetVariable(VariableSpace space, const char *name, const char *value)
VariableSpace CreateVariableSpace(void)