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:

Previous
From: Bruce Momjian
Date:
Subject: Re: LDAP auth
Next
From: Bruce Momjian
Date:
Subject: Re: [HACKERS] Zeroing damaged pages