On Wed, 7 Dec 2005, Andreas Seltenreich wrote:

> Sergey E. Koposov schrob:
> 
> > I submit the new version of my patch (against the CVS tip), correcting the 
> > problem with \edit (pointed by Andreas). So now everything works fine.
> 
> I think there's a pgflush_history() call missing somewhere, since the
> buffer isn't flushed on a control-c. The fresh query is appended to
> the aborted one in the history:

> Wouldn't it be more elegant to use the facilities in libpq's
> pqexpbuffer.h for the history buffer instead of passing the
> buffer-length around as a separate function argument and doing custom
> string operations?


Thank you, Andreas. I corrected the bug and also switched to pqexpbuffer 
instead of my own work with the strings.

The new patch is attached. 

> 
> The multi-line history entries are not preserved between psql
> invocations. Bash does solve this by folding multi-line commands into
> a single line where possible. But I have to admit, this could be sold
> as another TODO item :-)
> 

I also wanted this feature for a long time.
And I agree that it is rather simple to just remove the \n when writing to the
readline history file, but I don't think that's what everybody wants. I
think that people want to preserve the original formatting... 

So in that case the solution can be just putting some symbol instead of \n
in the history file, and during the loading of that file replace it back 
(that symbol can be zero byte for example). But I'm not sure that people 
will like that solution too.


Regards,
        Sergey

*****************************************************
Sergey E. Koposov
Max-Planck Institut for Astronomy
Web: http://lnfm1.sai.msu.ru/~math 
E-mail: [EMAIL PROTECTED]
Index: help.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/help.c,v
retrieving revision 1.106
diff -c -r1.106 help.c
*** help.c      15 Oct 2005 02:49:40 -0000      1.106
--- help.c      8 Dec 2005 01:40:14 -0000
***************
*** 7,12 ****
--- 7,13 ----
   */
  #include "postgres_fe.h"
  #include "common.h"
+ #include "pqexpbuffer.h"
  #include "input.h"
  #include "print.h"
  #include "help.h"
Index: input.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/input.c,v
retrieving revision 1.46
diff -c -r1.46 input.c
*** input.c     15 Oct 2005 02:49:40 -0000      1.46
--- input.c     8 Dec 2005 01:40:14 -0000
***************
*** 7,14 ****
   */
  #include "postgres_fe.h"
  
- #include "input.h"
  #include "pqexpbuffer.h"
  #include "settings.h"
  #include "tab-complete.h"
  #include "common.h"
--- 7,14 ----
   */
  #include "postgres_fe.h"
  
  #include "pqexpbuffer.h"
+ #include "input.h"
  #include "settings.h"
  #include "tab-complete.h"
  #include "common.h"
***************
*** 90,107 ****
  #ifdef USE_READLINE
        char       *s;
  
-       static char *prev_hist = NULL;
- 
        if (useReadline)
                /* On some platforms, readline is declared as readline(char *) 
*/
                s = readline((char *) prompt);
        else
                s = gets_basic(prompt);
  
!       if (useHistory && s && s[0])
        {
-               enum histcontrol HC;
  
                HC = GetHistControlConfig();
  
                if (((HC & hctl_ignorespace) && s[0] == ' ') ||
--- 90,146 ----
  #ifdef USE_READLINE
        char       *s;
  
        if (useReadline)
                /* On some platforms, readline is declared as readline(char *) 
*/
                s = readline((char *) prompt);
        else
                s = gets_basic(prompt);
  
!       return s;
! #else
!       return gets_basic(prompt);
! #endif
! }
! 
! /* Put the line in the history buffer and also add the trailing \n */
! void pgadd_history(char *s, PQExpBuffer history_buf)
! {
! #ifdef USE_READLINE
! 
!       int slen;
!       if (useReadline && useHistory && s && s[0])
!       {
!               slen = strlen(s);
!               if (s[slen-1]=='\n')
!               {
!                       appendPQExpBufferStr(history_buf, s);
!               }
!               else
!               {
!                       appendPQExpBufferStr(history_buf, s);
!                       appendPQExpBufferChar(history_buf, '\n');
!               }
!       }       
! #endif        
! }
! 
! 
! /* 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;
!       
!       if (useReadline && useHistory )
        {
  
+               enum histcontrol HC;
+               
+               s = history_buf->data;
+               prev_hist = NULL;
+                       
                HC = GetHistControlConfig();
  
                if (((HC & hctl_ignorespace) && s[0] == ' ') ||
***************
*** 112,130 ****
                else
                {
                        free(prev_hist);
                        prev_hist = pg_strdup(s);
                        add_history(s);
                }
        }
  
-       return s;
- #else
-       return gets_basic(prompt);
  #endif
  }
  
  
  
  /*
   * gets_fromFile
   *
--- 151,184 ----
                else
                {
                        free(prev_hist);
+                       slen = strlen(s);
+                       /* Trim the trailing \n's */
+                       for(i = slen-1; (i >= 0) && ( s[i] == '\n' ); i--);
+                       s[i + 1] = 0;
                        prev_hist = pg_strdup(s);
                        add_history(s);
                }
+               
+               resetPQExpBuffer(history_buf);
+       }
+ #endif
+ }
+ 
+ void pgclear_history(PQExpBuffer history_buf)
+ {
+ #ifdef USE_READLINE   
+       if (useReadline && useHistory )
+       {
+               resetPQExpBuffer(history_buf);
        }
  
  #endif
  }
  
  
  
+ 
+ 
  /*
   * gets_fromFile
   *
Index: input.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/input.h,v
retrieving revision 1.23
diff -c -r1.23 input.h
*** input.h     1 Jan 2005 05:43:08 -0000       1.23
--- input.h     8 Dec 2005 01:40:14 -0000
***************
*** 39,42 ****
--- 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 */
Index: mainloop.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/mainloop.c,v
retrieving revision 1.68
diff -c -r1.68 mainloop.c
*** mainloop.c  15 Oct 2005 02:49:40 -0000      1.68
--- mainloop.c  8 Dec 2005 01:40:14 -0000
***************
*** 37,42 ****
--- 37,43 ----
        PQExpBuffer query_buf;          /* buffer for query being accumulated */
        PQExpBuffer previous_buf;       /* if there isn't anything in the new 
buffer
                                                                 * yet, use 
this one for \e, etc. */
+       PQExpBuffer history_buf;
        char       *line;                       /* current line of input */
        int                     added_nl_pos;
        bool            success;
***************
*** 66,72 ****
  
        query_buf = createPQExpBuffer();
        previous_buf = createPQExpBuffer();
!       if (!query_buf || !previous_buf)
        {
                psql_error("out of memory\n");
                exit(EXIT_FAILURE);
--- 67,75 ----
  
        query_buf = createPQExpBuffer();
        previous_buf = createPQExpBuffer();
!       history_buf = createPQExpBuffer();
! 
!       if (!query_buf || !previous_buf || !history_buf)
        {
                psql_error("out of memory\n");
                exit(EXIT_FAILURE);
***************
*** 90,95 ****
--- 93,101 ----
                                successResult = EXIT_USER;
                                break;
                        }
+                       {
+                               pgclear_history(history_buf);                   
+                       }
  
                        cancel_pressed = false;
                }
***************
*** 100,111 ****
--- 106,120 ----
                        /* got here with longjmp */
  
                        /* reset parsing state */
+                       
                        resetPQExpBuffer(query_buf);
                        psql_scan_finish(scan_state);
                        psql_scan_reset(scan_state);
                        count_eof = 0;
                        slashCmdStatus = CMD_UNKNOWN;
                        prompt_status = PROMPT_READY;
+                       if (pset.cur_cmd_interactive)
+                               pgclear_history(history_buf);                   
  
                        if (pset.cur_cmd_interactive)
                                putc('\n', stdout);
***************
*** 138,143 ****
--- 147,161 ----
                        psql_scan_reset(scan_state);
                        slashCmdStatus = CMD_UNKNOWN;
                        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);
+                         }
+ 
                }
  
                /*
***************
*** 212,218 ****
                 */
                psql_scan_setup(scan_state, line, strlen(line));
                success = true;
! 
                while (success || !die_on_error)
                {
                        PsqlScanResult scan_result;
--- 230,242 ----
                 */
                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)
                {
                        PsqlScanResult scan_result;
***************
*** 229,234 ****
--- 253,259 ----
                                (scan_result == PSCAN_EOL &&
                                 GetVariableBool(pset.vars, "SINGLELINE")))
                        {
+                               
                                /* execute query */
                                success = SendQuery(query_buf->data);
                                slashCmdStatus = success ? CMD_SEND : CMD_ERROR;
***************
*** 249,258 ****
--- 274,286 ----
                                 * newline again.  This avoids any change to 
query_buf when a
                                 * line contains only a backslash command.
                                 */
+ 
+ 
                                if (query_buf->len == added_nl_pos)
                                        query_buf->data[--query_buf->len] = 
'\0';
                                added_nl_pos = -1;
  
+ 
                                slashCmdStatus = HandleSlashCmds(scan_state,
                                                                                
                 query_buf->len > 0 ?
                                                                                
                 query_buf : previous_buf);
***************
*** 266,271 ****
--- 294,300 ----
                                        appendPQExpBufferStr(query_buf, 
previous_buf->data);
                                }
  
+ 
                                if (slashCmdStatus == CMD_SEND)
                                {
                                        success = SendQuery(query_buf->data);
***************
*** 287,292 ****
--- 316,329 ----
                                scan_result == PSCAN_EOL)
                                break;
                }
+               
+               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);
***************
*** 333,338 ****
--- 370,376 ----
  
        destroyPQExpBuffer(query_buf);
        destroyPQExpBuffer(previous_buf);
+       destroyPQExpBuffer(history_buf);
  
        psql_scan_destroy(scan_state);
  
Index: prompt.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/prompt.c,v
retrieving revision 1.40
diff -c -r1.40 prompt.c
*** prompt.c    15 Oct 2005 02:49:40 -0000      1.40
--- prompt.c    8 Dec 2005 01:40:15 -0000
***************
*** 12,17 ****
--- 12,18 ----
  
  #include "settings.h"
  #include "common.h"
+ #include "pqexpbuffer.h"
  #include "input.h"
  #include "variables.h"
  
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Reply via email to