From ca8f27998a789af126bbd938c10b160b052a57a7 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 6 Mar 2006 04:45:21 +0000 Subject: [PATCH] In psql, save history of backslash commands used in multi-line statements before the multi-line statement, rather than inside the multi-line statement. --- src/bin/psql/input.c | 18 ++++++++---------- src/bin/psql/input.h | 8 ++++---- src/bin/psql/mainloop.c | 40 +++++++++++++++++++++++++++++++--------- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c index 241c5d356b..fdf0bbecdd 100644 --- a/src/bin/psql/input.c +++ b/src/bin/psql/input.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/input.c,v 1.51 2006/03/05 15:58:51 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/input.c,v 1.52 2006/03/06 04:45:21 momjian Exp $ */ #include "postgres_fe.h" @@ -114,7 +114,7 @@ gets_interactive(const char *prompt) /* Put the line in the history buffer and also add the trailing \n */ void -pgadd_history(char *s, PQExpBuffer history_buf) +pg_append_history(char *s, PQExpBuffer history_buf) { #ifdef USE_READLINE @@ -134,12 +134,13 @@ pgadd_history(char *s, PQExpBuffer history_buf) } -/* Feed the contents of the history buffer to readline */ +/* + * Feed the string to readline + */ void -pgflush_history(PQExpBuffer history_buf) +pg_write_history(char *s) { -#ifdef USE_READLINE - char *s; +#ifdef USE_READLINE static char *prev_hist; int slen, i; @@ -147,7 +148,6 @@ pgflush_history(PQExpBuffer history_buf) { enum histcontrol HC; - s = history_buf->data; prev_hist = NULL; HC = GetHistControlConfig(); @@ -168,14 +168,12 @@ pgflush_history(PQExpBuffer history_buf) prev_hist = pg_strdup(s); add_history(s); } - - resetPQExpBuffer(history_buf); } #endif } void -pgclear_history(PQExpBuffer history_buf) +pg_clear_history(PQExpBuffer history_buf) { #ifdef USE_READLINE if (useReadline && useHistory) diff --git a/src/bin/psql/input.h b/src/bin/psql/input.h index 89c18386d0..3b85d41670 100644 --- a/src/bin/psql/input.h +++ b/src/bin/psql/input.h @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/input.h,v 1.25 2006/03/05 15:58:51 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/input.h,v 1.26 2006/03/06 04:45:21 momjian Exp $ */ #ifndef INPUT_H #define INPUT_H @@ -39,9 +39,9 @@ char *gets_fromFile(FILE *source); void initializeInput(int flags); bool saveHistory(char *fname); -void pgadd_history(char *s, PQExpBuffer history_buf); -void pgclear_history(PQExpBuffer history_buf); -void pgflush_history(PQExpBuffer history_buf); +void pg_append_history(char *s, PQExpBuffer history_buf); +void pg_clear_history(PQExpBuffer history_buf); +void pg_write_history(char *s); #endif /* INPUT_H */ diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c index 9e85093c67..6cdbb9f482 100644 --- a/src/bin/psql/mainloop.c +++ b/src/bin/psql/mainloop.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/mainloop.c,v 1.71 2006/03/05 15:58:51 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/mainloop.c,v 1.72 2006/03/06 04:45:21 momjian Exp $ */ #include "postgres_fe.h" #include "mainloop.h" @@ -41,6 +41,8 @@ MainLoop(FILE *source) char *line; /* current line of input */ int added_nl_pos; bool success; + bool first_query_scan; + volatile int successResult = EXIT_SUCCESS; volatile backslashResult slashCmdStatus = PSQL_CMD_UNKNOWN; volatile promptStatus_t prompt_status = PROMPT_READY; @@ -93,7 +95,7 @@ MainLoop(FILE *source) successResult = EXIT_USER; break; } - pgclear_history(history_buf); + pg_clear_history(history_buf); cancel_pressed = false; } @@ -110,7 +112,7 @@ MainLoop(FILE *source) slashCmdStatus = PSQL_CMD_UNKNOWN; prompt_status = PROMPT_READY; if (pset.cur_cmd_interactive) - pgclear_history(history_buf); + pg_clear_history(history_buf); if (pset.cur_cmd_interactive) putc('\n', stdout); @@ -145,11 +147,14 @@ MainLoop(FILE *source) prompt_status = PROMPT_READY; if (pset.cur_cmd_interactive) + { /* * Pass all the contents of history_buf to readline * and free the history buffer. */ - pgflush_history(history_buf); + pg_write_history(history_buf->data); + pg_clear_history(history_buf); + } } /* otherwise, get another line */ else if (pset.cur_cmd_interactive) @@ -221,10 +226,7 @@ MainLoop(FILE *source) */ psql_scan_setup(scan_state, line, strlen(line)); success = true; - - if (pset.cur_cmd_interactive) - /* Put current line in the history buffer */ - pgadd_history(line, history_buf); + first_query_scan = true; while (success || !die_on_error) { @@ -235,6 +237,23 @@ MainLoop(FILE *source) prompt_status = prompt_tmp; /* + * If we append to history a backslash command that is inside + * a multi-line query, then when we recall the history, the + * backslash command will make the query invalid, so we write + * backslash commands immediately rather than keeping them + * as part of the current multi-line query. + */ + if (first_query_scan && pset.cur_cmd_interactive) + { + if (scan_result == PSCAN_BACKSLASH && query_buf->len != 0) + pg_write_history(line); + else + pg_append_history(line, history_buf); + } + + first_query_scan = false; + + /* * Send command if semicolon found, or if end of line and we're in * single-line mode. */ @@ -302,11 +321,14 @@ MainLoop(FILE *source) } if (pset.cur_cmd_interactive && prompt_status != PROMPT_CONTINUE) + { /* * Pass all the contents of history_buf to readline * and free the history buffer. */ - pgflush_history(history_buf); + pg_write_history(history_buf->data); + pg_clear_history(history_buf); + } psql_scan_finish(scan_state); free(line); -- 2.11.0