summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian2006-03-06 04:45:21 +0000
committerBruce Momjian2006-03-06 04:45:21 +0000
commit6a05b8a02964838271dd3bc401666876eaf4c4e6 (patch)
tree2e9c9e9e0150b1e3b26a7354982f7eefc1a8a672
parent0847cba3beab6bd5266e6af69bf11bd87135f6c0 (diff)
In psql, save history of backslash commands used in multi-line
statements before the multi-line statement, rather than inside the multi-line statement.
-rw-r--r--src/bin/psql/input.c16
-rw-r--r--src/bin/psql/input.h6
-rw-r--r--src/bin/psql/mainloop.c38
3 files changed, 40 insertions, 20 deletions
diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c
index affe2e84bd..e5360e8895 100644
--- a/src/bin/psql/input.c
+++ b/src/bin/psql/input.c
@@ -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 03a3024ecd..77d0e8f9d4 100644
--- a/src/bin/psql/input.h
+++ b/src/bin/psql/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 fa6ec03382..11daa3c771 100644
--- a/src/bin/psql/mainloop.c
+++ b/src/bin/psql/mainloop.c
@@ -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);