From 0155a5573e7ff9a187f788c0e12096fe9a7d8ac7 Mon Sep 17 00:00:00 2001 From: Greg Nancarrow Date: Mon, 6 Sep 2021 23:10:35 +1000 Subject: [PATCH] Correct handling of blank/commented lines in PSQL interactive-mode history. Improve PSQL interactive-mode history, for lines that are not part of a line continuation, by storing them in the history as separate entries if they only contain whitespace or an SQL comment. (Note that lines starting with a space don't get saved in the history if HISTCONTROL=ignorespace is in effect) Currently, such blank or commented lines are prepended to the history entry for the next command entered. Worse, if HISTCONTROL=ignorespace is in effect, and the line starts with a space and the rest is whitespace or an SQL comment, it prevents the next command entered from being saved in the history. --- src/bin/psql/mainloop.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c index e49ed02293..cf8b0076c0 100644 --- a/src/bin/psql/mainloop.c +++ b/src/bin/psql/mainloop.c @@ -47,6 +47,7 @@ MainLoop(FILE *source) volatile int successResult = EXIT_SUCCESS; volatile backslashResult slashCmdStatus = PSQL_CMD_UNKNOWN; volatile promptStatus_t prompt_status = PROMPT_READY; + volatile PsqlScanResult scan_result = PSCAN_INCOMPLETE; volatile bool need_redisplay = false; volatile int count_eof = 0; volatile bool die_on_error = false; @@ -119,6 +120,7 @@ MainLoop(FILE *source) count_eof = 0; slashCmdStatus = PSQL_CMD_UNKNOWN; prompt_status = PROMPT_READY; + scan_result = PSCAN_INCOMPLETE; need_redisplay = false; pset.stmt_lineno = 1; cancel_pressed = false; @@ -388,7 +390,6 @@ MainLoop(FILE *source) while (success || !die_on_error) { - PsqlScanResult scan_result; promptStatus_t prompt_tmp = prompt_status; size_t pos_in_query; char *tmp_line; @@ -564,9 +565,25 @@ MainLoop(FILE *source) break; } - /* Add line to pending history if we didn't execute anything yet */ + /* + * If we didn't execute anything yet, then depending on the scan and + * prompt state, either save the line to the history or just add the + * line to the pending history. + */ if (pset.cur_cmd_interactive && !line_saved_in_history) + { pg_append_history(line, history_buf); + if (scan_result == PSCAN_INCOMPLETE && prompt_status == PROMPT_READY) + { + /* + * In this case, it's not a line continuation, and the line + * contains only whitespace or a single-line SQL comment, so + * save it to the history. + */ + pg_send_history(history_buf); + line_saved_in_history = true; + } + } psql_scan_finish(scan_state); free(line); -- 2.27.0