2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2025, PostgreSQL Global Development Group
23 #define PSQLHISTORY ".psql_history"
25#define PSQLHISTORY "psql_history"
28/* Runtime options for turning off readline and history */
29/* (of course there is no runtime command for doing that :) */
31static bool useReadline;
32static bool useHistory;
34static char *psql_history;
36static int history_lines_added;
40 * Preserve newlines in saved queries by mapping '\n' to NL_IN_HISTORY
42 * It is assumed NL_IN_HISTORY will never be entered by the user
43 * nor appear inside a multi-byte string. 0x00 is not properly
44 * handled by the readline routines so it can not be used
47#define NL_IN_HISTORY 0x01
56 * Gets a line of interactive input, using readline if desired.
58 * prompt: the prompt string to be used
59 * query_buf: buffer containing lines already read in the current command
60 * (query_buf is not modified here, but may be consulted for tab completion)
62 * The result is a malloc'd string.
64 * Caller *must* have set up sigint_interrupt_jmp before calling.
75 * Some versions of readline don't notice SIGWINCH signals that arrive
76 * when not actively reading input. The simplest fix is to always
77 * re-read the terminal size. This leaves a window for SIGWINCH to be
78 * missed between here and where readline() enables libreadline's
79 * signal handler, but that's probably short enough to be ignored.
81#ifdef HAVE_RL_RESET_SCREEN_SIZE
82 rl_reset_screen_size();
85 /* Make current query_buf available to tab completion callback */
88 /* Enable SIGINT to longjmp to sigint_interrupt_jmp */
91 result = readline(prompt);
93 /* Disable SIGINT again */
96 /* Pure neatnik-ism */
110 * Append the line to the history buffer, making sure there is a trailing '\n'
119 if (!s[0] || s[strlen(s) - 1] !=
'\n')
127 * Emit accumulated history entry to readline's history mechanism,
128 * then reset the buffer to empty.
130 * Note: we write nothing if history_buf is empty, so extra calls to this
131 * function don't hurt. There must have been at least one line added by
132 * pg_append_history before we'll do anything.
138 static char *prev_hist = NULL;
140 char *s = history_buf->
data;
143 /* Trim any trailing \n's (OK to scribble on history_buf) */
144 for (
i = strlen(s) - 1;
i >= 0 && s[
i] ==
'\n';
i--)
148 if (useHistory && s[0])
153 prev_hist && strcmp(s, prev_hist) == 0))
155 /* Ignore this line as far as history is concerned */
159 /* Save each previous line for ignoredups processing */
162 /* And send it to readline */
164 /* Count lines added to history for use later */
165 history_lines_added++;
177 * Gets a line of noninteractive input from a file (which could be stdin).
178 * The result is a malloc'd string, or NULL on EOF or input error.
180 * Caller *must* have set up sigint_interrupt_jmp before calling.
182 * Note: we re-use a static PQExpBuffer for each call. This is to avoid
183 * leaking memory if interrupted by SIGINT.
192 if (buffer == NULL)
/* first time through? */
201 /* Enable SIGINT to longjmp to sigint_interrupt_jmp */
205 result = fgets(line,
sizeof(line),
source);
207 /* Disable SIGINT again */
230 if (buffer->
len > 0 && buffer->
data[buffer->
len - 1] ==
'\n')
232 buffer->
data[buffer->
len - 1] =
'0円';
237 if (buffer->
len > 0)
/* EOF after reading some bufferload(s) */
240 /* EOF, so return null */
248 * Macros to iterate over each element of the history list in order
250 * You would think this would be simple enough, but in its inimitable fashion
251 * libedit has managed to break it: in libreadline we must use next_history()
252 * to go from oldest to newest, but in libedit we must use previous_history().
253 * To detect what to do, we make a trial call of previous_history(): if it
254 * fails, then either next_history() is what to use, or there's zero or one
255 * history entry so that it doesn't matter which direction we go.
257 * In case that wasn't disgusting enough: the code below is not as obvious as
258 * it might appear. In some libedit releases history_set_pos(0) fails until
259 * at least one add_history() call has been done. This is not an issue for
260 * printHistory() or encode_history(), which cannot be invoked before that has
261 * happened. In decode_history(), that's not so, and what actually happens is
262 * that we are sitting on the newest entry to start with, previous_history()
263 * fails, and we iterate over all the entries using next_history(). So the
264 * decode_history() loop iterates over the entries in the wrong order when
265 * using such a libedit release, and if there were another attempt to use
266 * BEGIN_ITERATE_HISTORY() before some add_history() call had happened, it
267 * wouldn't work. Fortunately we don't care about either of those things.
271 * BEGIN_ITERATE_HISTORY(varname);
273 * loop body referencing varname->line;
275 * END_ITERATE_HISTORY();
277#define BEGIN_ITERATE_HISTORY(VARNAME) \
279 HIST_ENTRY *VARNAME; \
282 history_set_pos(0); \
283 use_prev_ = (previous_history() != NULL); \
284 history_set_pos(0); \
285 for (VARNAME = current_history(); VARNAME != NULL; \
286 VARNAME = use_prev_ ? previous_history() : next_history()) \
290#define END_ITERATE_HISTORY() \
296 * Convert newlines to NL_IN_HISTORY for safe saving in readline history file
301 BEGIN_ITERATE_HISTORY(cur_hist);
305 /* some platforms declare HIST_ENTRY.line as const char * */
306 for (cur_ptr = (
char *) cur_hist->line; *cur_ptr; cur_ptr++)
308 if (*cur_ptr ==
'\n')
309 *cur_ptr = NL_IN_HISTORY;
312 END_ITERATE_HISTORY();
316 * Reverse the above encoding
321 BEGIN_ITERATE_HISTORY(cur_hist);
325 /* some platforms declare HIST_ENTRY.line as const char * */
326 for (cur_ptr = (
char *) cur_hist->line; *cur_ptr; cur_ptr++)
328 if (*cur_ptr == NL_IN_HISTORY)
332 END_ITERATE_HISTORY();
334#endif /* USE_READLINE */
338 * Put any startup stuff related to input in here. It's good to maintain
339 * abstraction this way.
341 * The only "flag" right now is 1 for use readline & history.
349 const char *histfile;
354 /* set appropriate values for Readline's global variables */
357#ifdef HAVE_RL_VARIABLE_BIND
358 /* set comment-begin to a useful value for SQL */
359 (void) rl_variable_bind(
"comment-begin",
"-- ");
362 /* this reads ~/.inputrc, so do it after rl_variable_bind */
367 history_lines_added = 0;
371 if (histfile == NULL)
375 envhist = getenv(
"PSQL_HISTORY");
376 if (envhist != NULL && strlen(envhist) > 0)
380 if (histfile == NULL)
393 read_history(psql_history);
404 * This function saves the readline history when psql exits.
406 * fname: pathname of history file. (Should really be "const char *",
407 * but some ancient versions of readline omit the const-decoration.)
409 * max_lines: if >= 0, limit history file to that many entries.
413saveHistory(
char *fname,
int max_lines)
418 * Suppressing the write attempt when HISTFILE is set to /dev/null may
419 * look like a negligible optimization, but it's necessary on e.g. macOS,
420 * where write_history will fail because it tries to chmod the target
423 if (strcmp(fname,
DEVNULL) != 0)
426 * Encode \n, since otherwise readline will reload multiline history
427 * entries as separate lines. (libedit doesn't really need this, but
428 * we do it anyway since it's too hard to tell which implementation we
434 * On newer versions of libreadline, truncate the history file as
435 * needed and then append what we've added. This avoids overwriting
436 * history from other concurrent sessions (although there are still
437 * race conditions when two sessions exit at about the same time). If
438 * we don't have those functions, fall back to write_history().
440#if defined(HAVE_HISTORY_TRUNCATE_FILE) && defined(HAVE_APPEND_HISTORY)
445 /* truncate previous entries if needed */
448 nlines =
Max(max_lines - history_lines_added, 0);
449 (void) history_truncate_file(fname, nlines);
451 /* append_history fails if file doesn't already exist :-( */
452 fd = open(fname, O_CREAT | O_WRONLY |
PG_BINARY, 0600);
455 /* append the appropriate number of lines */
457 nlines =
Min(max_lines, history_lines_added);
459 nlines = history_lines_added;
460 errnum = append_history(nlines, fname);
464#else /* don't have append support */
466 /* truncate what we have ... */
468 stifle_history(max_lines);
469 /* ... and overwrite file. Tough luck for concurrent sessions. */
470 errnum = write_history(fname);
476 pg_log_error(
"could not save history to file \"%s\": %m", fname);
485 * Print history to the specified file, or to the console if fname is NULL
488 * We used to use saveHistory() for this purpose, but that doesn't permit
489 * use of a pager; moreover libedit's implementation behaves incompatibly
490 * (preferring to encode its output) and may fail outright when the target
491 * file is specified as /dev/tty.
505 /* use pager, if enabled, when printing to console */
511 output = fopen(fname,
"w");
514 pg_log_error(
"could not save history to file \"%s\": %m", fname);
520 BEGIN_ITERATE_HISTORY(cur_hist);
524 END_ITERATE_HISTORY();
533 pg_log_error(
"history is not supported by this installation");
543 if (useHistory && psql_history)
void expand_tilde(char **filename)
volatile sig_atomic_t sigint_interrupt_enabled
#define fprintf(file, fmt, msg)
char * pg_strdup(const char *in)
FILE * PageOutput(int lines, const printTableOpt *topt)
void ClosePager(FILE *pagerpipe)
#define pg_log_error(...)
static rewind_source * source
bool get_home_path(char *ret_path)
PQExpBuffer createPQExpBuffer(void)
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
#define PQExpBufferBroken(str)
static int fd(const char *x, int i)
char * psprintf(const char *fmt,...)
void initialize_readline(void)
PQExpBuffer tab_completion_query_buf
const char * GetVariable(VariableSpace space, const char *name)