Re: fix of some issues with multi-line query editing - Mailing list pgsql-patches
| From | Bruce Momjian |
|---|---|
| Subject | Re: fix of some issues with multi-line query editing |
| Date | |
| Msg-id | 200603060447.k264lO211093@candle.pha.pa.us Whole thread Raw |
| In response to | fix of some issues with multi-line query editing ("Sergey E. Koposov" <math@sai.msu.ru>) |
| Responses |
Re: fix of some issues with multi-line query editing
|
| List | pgsql-patches |
I have applied the following patch which saves psql history for
backslash commands used in multi-line statements before the command,
rather than inside it, e.g:
test=> SELECT
test-> \d
No relations found.
test-> 1;
?column?
----------
1
(1 row)
has history in this order:
test=> \d
No relations found.
test=> SELECT
1;
?column?
----------
1
(1 row)
I also renamed some of the history functions for clarity.
---------------------------------------------------------------------------
Sergey E. Koposov wrote:
> Fix of several issues:
>
> 1) Fix the problems with the \s command.
> When the saveHistory is executed by the \s command we must not do the
> conversion \n -> \x01 (per
> http://archives.postgresql.org/pgsql-hackers/2006-03/msg00317.php )
>
> 2) Fix the handling of Ctrl+C
>
> Now when you do
> wsdb=# select 'your long query here '
> wsdb-#
> and press afterwards the CtrlC the line "select 'your long query here '"
> will be in the history
>
> (partly per
> http://archives.postgresql.org/pgsql-hackers/2006-03/msg00297.php )
>
> 3) Fix the handling of commands with not closed brackets, quotes, double
> quotes. (now those commands are not splitted in parts...)
>
> 4) Fix the behaviour when SINGLELINE mode is used. (before it was almost
> broken ;(
>
> Regards,
> Sergey
>
> *****************************************************
> Sergey E. Koposov
> Max Planck Institute for Astronomy
> Web: http://lnfm1.sai.msu.ru/~math
> E-mail: math@sai.msu.ru
>
>
>
Content-Description:
[ Attachment, skipping... ]
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: don't forget to increase your free space map settings
--
Bruce Momjian http://candle.pha.pa.us
SRA OSS, Inc. http://www.sraoss.com
+ If your life is a hard drive, Christ can be your backup. +
Index: src/bin/psql/input.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/input.c,v
retrieving revision 1.51
diff -c -c -r1.51 input.c
*** src/bin/psql/input.c 5 Mar 2006 15:58:51 -0000 1.51
--- src/bin/psql/input.c 6 Mar 2006 02:38:05 -0000
***************
*** 114,120 ****
/* Put the line in the history buffer and also add the trailing \n */
void
! pgadd_history(char *s, PQExpBuffer history_buf)
{
#ifdef USE_READLINE
--- 114,120 ----
/* Put the line in the history buffer and also add the trailing \n */
void
! pg_append_history(char *s, PQExpBuffer history_buf)
{
#ifdef USE_READLINE
***************
*** 134,145 ****
}
! /* Feed the contents of the history buffer to readline */
void
! pgflush_history(PQExpBuffer history_buf)
{
! #ifdef USE_READLINE
! char *s;
static char *prev_hist;
int slen, i;
--- 134,146 ----
}
! /*
! * Feed the string to readline
! */
void
! pg_write_history(char *s)
{
! #ifdef USE_READLINE
static char *prev_hist;
int slen, i;
***************
*** 147,153 ****
{
enum histcontrol HC;
- s = history_buf->data;
prev_hist = NULL;
HC = GetHistControlConfig();
--- 148,153 ----
***************
*** 168,181 ****
prev_hist = pg_strdup(s);
add_history(s);
}
-
- resetPQExpBuffer(history_buf);
}
#endif
}
void
! pgclear_history(PQExpBuffer history_buf)
{
#ifdef USE_READLINE
if (useReadline && useHistory)
--- 168,179 ----
prev_hist = pg_strdup(s);
add_history(s);
}
}
#endif
}
void
! pg_clear_history(PQExpBuffer history_buf)
{
#ifdef USE_READLINE
if (useReadline && useHistory)
Index: src/bin/psql/input.h
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/input.h,v
retrieving revision 1.25
diff -c -c -r1.25 input.h
*** src/bin/psql/input.h 5 Mar 2006 15:58:51 -0000 1.25
--- src/bin/psql/input.h 6 Mar 2006 02:38:05 -0000
***************
*** 39,47 ****
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);
#endif /* INPUT_H */
--- 39,47 ----
void initializeInput(int flags);
bool saveHistory(char *fname);
! 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 */
Index: src/bin/psql/mainloop.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/mainloop.c,v
retrieving revision 1.71
diff -c -c -r1.71 mainloop.c
*** src/bin/psql/mainloop.c 5 Mar 2006 15:58:51 -0000 1.71
--- src/bin/psql/mainloop.c 6 Mar 2006 02:38:05 -0000
***************
*** 41,46 ****
--- 41,48 ----
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,99 ****
successResult = EXIT_USER;
break;
}
! pgclear_history(history_buf);
cancel_pressed = false;
}
--- 95,101 ----
successResult = EXIT_USER;
break;
}
! pg_clear_history(history_buf);
cancel_pressed = false;
}
***************
*** 110,116 ****
slashCmdStatus = PSQL_CMD_UNKNOWN;
prompt_status = PROMPT_READY;
if (pset.cur_cmd_interactive)
! pgclear_history(history_buf);
if (pset.cur_cmd_interactive)
putc('\n', stdout);
--- 112,118 ----
slashCmdStatus = PSQL_CMD_UNKNOWN;
prompt_status = PROMPT_READY;
if (pset.cur_cmd_interactive)
! pg_clear_history(history_buf);
if (pset.cur_cmd_interactive)
putc('\n', stdout);
***************
*** 145,155 ****
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);
}
/* otherwise, get another line */
else if (pset.cur_cmd_interactive)
--- 147,160 ----
prompt_status = PROMPT_READY;
if (pset.cur_cmd_interactive)
+ {
/*
* Pass all the contents of history_buf to readline
* and free the history buffer.
*/
! pg_write_history(history_buf->data);
! pg_clear_history(history_buf);
! }
}
/* otherwise, get another line */
else if (pset.cur_cmd_interactive)
***************
*** 221,230 ****
*/
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);
while (success || !die_on_error)
{
--- 226,232 ----
*/
psql_scan_setup(scan_state, line, strlen(line));
success = true;
! first_query_scan = true;
while (success || !die_on_error)
{
***************
*** 235,240 ****
--- 237,259 ----
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,312 ****
}
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);
psql_scan_finish(scan_state);
free(line);
--- 321,334 ----
}
if (pset.cur_cmd_interactive && prompt_status != PROMPT_CONTINUE)
+ {
/*
* Pass all the contents of history_buf to readline
* and free the history buffer.
*/
! pg_write_history(history_buf->data);
! pg_clear_history(history_buf);
! }
psql_scan_finish(scan_state);
free(line);
pgsql-patches by date: