Re: psql patch (2) - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: psql patch (2)
Date
Msg-id 200303200645.h2K6jVv21120@candle.pha.pa.us
Whole thread Raw
In response to psql patch (2)  ("Jeroen T. Vermeulen" <jtv@xs4all.nl>)
Responses Re: psql patch (2)  ("Jeroen T. Vermeulen" <jtv@xs4all.nl>)
List pgsql-patches
Patch applied.  Thanks.

I have attached the patch. I adjusted the cancelConn functions.

I also adjusted this:

    + char parse_char(char **buf)
    + {
    +   long l;
    +
    +   l = strtol(*buf, buf, 0);
    +   (*buf)--;
    +   return (char)l;
    + }
    +

I added the parens around 'buf' because the compiler was saying
statement has no effect.  Is this correct?

---------------------------------------------------------------------------


Jeroen T. Vermeulen wrote:
> I'm continuing to work on cleaning up code in psql.  As things appear
> now, my changes seem to work.  Some possible minor bugs got squished
> on the way but I can't be sure without more feedback from people who
> really put the code to the test.
>
> The new patch mostly simplifies variable handling and reduces code
> duplication.  Changes in the command parser eliminate some redundant
> variables (boolean state + depth counter), replaces some
> "else if" constructs with switches, and so on.  It is meant to be
> applied together with my previous patch, although I hope they don't
> conflict; I went back to the CVS version for this one.
>
> One more thing I thought should perhaps be changed: an IGNOREEOF
> value of n will ignore only n-1 EOFs.  I didn't want to touch this
> for fear of breaking existing applications, but it does seem a tad
> illogical.
>
>
> Jeroen
>

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
> http://archives.postgresql.org

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: src/bin/psql/command.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/command.c,v
retrieving revision 1.93
diff -c -c -r1.93 command.c
*** src/bin/psql/command.c    19 Mar 2003 22:49:43 -0000    1.93
--- src/bin/psql/command.c    20 Mar 2003 06:42:19 -0000
***************
*** 669,683 ****
          if (!opt0)
          {
              /* list all variables */
!
!             /*
!              * XXX This is in utter violation of the GetVariable
!              * abstraction, but I have not bothered to do it better.
!              */
!             struct _variable *ptr;
!
!             for (ptr = pset.vars; ptr->next; ptr = ptr->next)
!                 fprintf(stdout, "%s = '%s'\n", ptr->next->name, ptr->next->value);
              success = true;
          }
          else
--- 669,675 ----
          if (!opt0)
          {
              /* list all variables */
!             PrintVariables(pset.vars);
              success = true;
          }
          else
***************
*** 1073,1081 ****
                  save_char = options_string[pos + token_end + 1];
                  options_string[pos + token_end + 1] = '\0';
                  value = GetVariable(pset.vars, options_string + pos + 1);
!                 if (!value)
!                     value = "";
!                 return_val = xstrdup(value);
                  options_string[pos + token_end + 1] = save_char;
                  *string = &options_string[pos + token_end + 1];
                  /* XXX should we set *quote to ':' here? */
--- 1065,1071 ----
                  save_char = options_string[pos + token_end + 1];
                  options_string[pos + token_end + 1] = '\0';
                  value = GetVariable(pset.vars, options_string + pos + 1);
!                 return_val = xstrdup(value ? value : "");
                  options_string[pos + token_end + 1] = save_char;
                  *string = &options_string[pos + token_end + 1];
                  /* XXX should we set *quote to ':' here? */
***************
*** 1287,1301 ****
                  case '7':
                  case '8':
                  case '9':
!                     {
!                         long int    l;
!                         char       *end;
!
!                         l = strtol(p, &end, 0);
!                         c = (char) l;
!                         p = end - 1;
                          break;
!                     }
                  default:
                      c = *p;
              }
--- 1277,1285 ----
                  case '7':
                  case '8':
                  case '9':
!                     c = parse_char((char **)&p);
                          break;
!
                  default:
                      c = *p;
              }
Index: src/bin/psql/common.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/common.c,v
retrieving revision 1.59
diff -c -c -r1.59 common.c
*** src/bin/psql/common.c    20 Mar 2003 06:00:12 -0000    1.59
--- src/bin/psql/common.c    20 Mar 2003 06:42:19 -0000
***************
*** 368,374 ****
  {
      PGresult   *res = NULL;
      PGresult   *newres;
!     const char *var;
      ExecStatusType rstatus;

      if (!pset.db)
--- 368,374 ----
  {
      PGresult   *res = NULL;
      PGresult   *newres;
!     int    echo_hidden;
      ExecStatusType rstatus;

      if (!pset.db)
***************
*** 377,393 ****
          return NULL;
      }

!     var = GetVariable(pset.vars, "ECHO_HIDDEN");
!     if (var)
      {
          printf("********* QUERY **********\n"
                 "%s\n"
                 "**************************\n\n", query);
          fflush(stdout);
-     }

!     if (var && strcmp(var, "noexec") == 0)
          return NULL;

      /* discard any uneaten results of past queries */
      while ((newres = PQgetResult(pset.db)) != NULL)
--- 377,393 ----
          return NULL;
      }

!     echo_hidden = SwitchVariable(pset.vars, "ECHO_HIDDEN", "noexec", NULL);
!     if (echo_hidden != var_notset)
      {
          printf("********* QUERY **********\n"
                 "%s\n"
                 "**************************\n\n", query);
          fflush(stdout);

!         if (echo_hidden == 1)
          return NULL;
+     }

      /* discard any uneaten results of past queries */
      while ((newres = PQgetResult(pset.db)) != NULL)
***************
*** 579,591 ****
      bool OK;

      if (!pset.db)
!             {
          psql_error("You are currently not connected to a database.\n");
          return false;
!             }

      if (GetVariableBool(pset.vars, "SINGLESTEP"))
!             {
          char        buf[3];

          printf(gettext("***(Single step mode: Verify query)*********************************************\n"
--- 579,591 ----
      bool OK;

      if (!pset.db)
!     {
          psql_error("You are currently not connected to a database.\n");
          return false;
!     }

      if (GetVariableBool(pset.vars, "SINGLESTEP"))
!     {
          char        buf[3];

          printf(gettext("***(Single step mode: Verify query)*********************************************\n"
***************
*** 596,609 ****
          if (fgets(buf, sizeof(buf), stdin) != NULL)
              if (buf[0] == 'x')
                  return false;
-             }
-             else
-         {
-         const char *var = GetVariable(pset.vars, "ECHO");
-
-         if (var && strncmp(var, "queries", strlen(var)) == 0)
-             puts(query);
      }

      SetCancelConn();

--- 596,604 ----
          if (fgets(buf, sizeof(buf), stdin) != NULL)
              if (buf[0] == 'x')
                  return false;
      }
+     else if (VariableEquals(pset.vars, "ECHO", "queries"))
+         puts(query);

      SetCancelConn();

***************
*** 619,621 ****
--- 614,628 ----
      PrintNotifications();
      return OK;
  }
+
+
+ char parse_char(char **buf)
+ {
+   long l;
+
+   l = strtol(*buf, buf, 0);
+   (*buf)--;
+   return (char)l;
+ }
+
+
Index: src/bin/psql/common.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/common.h,v
retrieving revision 1.23
diff -c -c -r1.23 common.h
*** src/bin/psql/common.h    20 Mar 2003 06:00:12 -0000    1.23
--- src/bin/psql/common.h    20 Mar 2003 06:42:19 -0000
***************
*** 42,47 ****
--- 42,53 ----
  /* sprompt.h */
  extern char *simple_prompt(const char *prompt, int maxlen, bool echo);

+ /* Parse a numeric character code from the string pointed at by *buf, e.g.
+  * one written as 0x0c (hexadecimal) or 015 (octal); advance *buf to the last
+  * character of the numeric character code.
+  */
+ extern char parse_char(char **buf);
+
  /* Used for all Win32 popen/pclose calls */
  #ifdef WIN32
  #define popen(x,y) _popen(x,y)
Index: src/bin/psql/input.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/input.c,v
retrieving revision 1.22
diff -c -c -r1.22 input.c
*** src/bin/psql/input.c    20 Mar 2003 06:00:12 -0000    1.22
--- src/bin/psql/input.c    20 Mar 2003 06:42:19 -0000
***************
*** 233,242 ****
                                      strlen(PSQLHISTORY) + 1);
              if (psql_history)
              {
!                 const char *var = GetVariable(pset.vars, "HISTSIZE");

-                 if (var)
-                     stifle_history(atoi(var));
                  sprintf(psql_history, "%s/%s", home, PSQLHISTORY);
                  write_history(psql_history);
                  free(psql_history);
--- 233,244 ----
                                      strlen(PSQLHISTORY) + 1);
              if (psql_history)
              {
!                 int hist_size;
!                 hist_size = GetVariableNum(pset.vars,"HISTSIZE",-1,-1,true);
!
!                 if (hist_size >= 0)
!                     stifle_history(hist_size);

                  sprintf(psql_history, "%s/%s", home, PSQLHISTORY);
                  write_history(psql_history);
                  free(psql_history);
Index: src/bin/psql/large_obj.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/large_obj.c,v
retrieving revision 1.23
diff -c -c -r1.23 large_obj.c
*** src/bin/psql/large_obj.c    15 Oct 2002 02:24:16 -0000    1.23
--- src/bin/psql/large_obj.c    20 Mar 2003 06:42:19 -0000
***************
*** 40,54 ****
  static bool
  handle_transaction(void)
  {
-     const char *var = GetVariable(pset.vars, "LO_TRANSACTION");
      PGresult   *res;
!     bool        commit;
      PQnoticeProcessor old_notice_hook;

!     if (var && strcmp(var, "nothing") == 0)
          return true;
!
!     commit = (var && strcmp(var, "commit") == 0);

      notice[0] = '\0';
      old_notice_hook = PQsetNoticeProcessor(pset.db, _my_notice_handler, NULL);
--- 40,59 ----
  static bool
  handle_transaction(void)
  {
      PGresult   *res;
!     bool        commit = false;
      PQnoticeProcessor old_notice_hook;

!     switch (SwitchVariable(pset.vars, "LO_TRANSACTION",
!                                     "nothing",
!                                     "commit",
!                                     NULL))
!     {
!       case 1:
          return true;
!       case 2:
!          commit = true;
!     }

      notice[0] = '\0';
      old_notice_hook = PQsetNoticeProcessor(pset.db, _my_notice_handler, NULL);
***************
*** 87,97 ****
  {
      PGresult   *res;
      int            status;
!     bool        own_transaction = true;
!     const char *var = GetVariable(pset.vars, "LO_TRANSACTION");

!     if (var && strcmp(var, "nothing") == 0)
!         own_transaction = false;

      if (!pset.db)
      {
--- 92,100 ----
  {
      PGresult   *res;
      int            status;
!     bool        own_transaction;

!     own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing");

      if (!pset.db)
      {
***************
*** 154,164 ****
      Oid            loid;
      char        oidbuf[32];
      unsigned int i;
!     bool        own_transaction = true;
!     const char *var = GetVariable(pset.vars, "LO_TRANSACTION");

!     if (var && strcmp(var, "nothing") == 0)
!         own_transaction = false;

      if (!pset.db)
      {
--- 157,165 ----
      Oid            loid;
      char        oidbuf[32];
      unsigned int i;
!     bool        own_transaction;

!     own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing");

      if (!pset.db)
      {
***************
*** 271,281 ****
      int            status;
      Oid            loid = atooid(loid_arg);
      char        buf[256];
-     bool        own_transaction = true;
-     const char *var = GetVariable(pset.vars, "LO_TRANSACTION");

!     if (var && strcmp(var, "nothing") == 0)
!         own_transaction = false;

      if (!pset.db)
      {
--- 272,281 ----
      int            status;
      Oid            loid = atooid(loid_arg);
      char        buf[256];

!     bool        own_transaction;
!
!     own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing");

      if (!pset.db)
      {
Index: src/bin/psql/mainloop.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/mainloop.c,v
retrieving revision 1.52
diff -c -c -r1.52 mainloop.c
*** src/bin/psql/mainloop.c    20 Mar 2003 06:00:12 -0000    1.52
--- src/bin/psql/mainloop.c    20 Mar 2003 06:42:25 -0000
***************
*** 40,55 ****
      char       *line;            /* current line of input */
      int            len;            /* length of the line */
      volatile int successResult = EXIT_SUCCESS;
!     volatile backslashResult slashCmdStatus;

      bool        success;
!     volatile char in_quote;        /* == 0 for no in_quote */
!     volatile bool in_xcomment;    /* in extended comment */
!     volatile int xcdepth;
!     volatile int paren_level;
      unsigned int query_start;
      volatile int count_eof = 0;
-     const char *var;
      volatile unsigned int bslash_count = 0;

      int            i,
--- 40,53 ----
      char       *line;            /* current line of input */
      int            len;            /* length of the line */
      volatile int successResult = EXIT_SUCCESS;
!     volatile backslashResult slashCmdStatus = CMD_UNKNOWN;

      bool        success;
!     volatile char in_quote = 0;        /* == 0 for no in_quote */
!     volatile int in_xcomment = 0;    /* in extended comment */
!     volatile int paren_level = 0;
      unsigned int query_start;
      volatile int count_eof = 0;
      volatile unsigned int bslash_count = 0;

      int            i,
***************
*** 81,96 ****
          exit(EXIT_FAILURE);
      }

-     in_xcomment = false;
-     in_quote = 0;
-     paren_level = 0;
-     slashCmdStatus = CMD_UNKNOWN;        /* set default */
      prev_lineno = pset.lineno;
      pset.lineno = 0;


      /* main loop to get queries and execute them */
!     while (1)
      {
          /*
           * Welcome code for Control-C
--- 79,90 ----
          exit(EXIT_FAILURE);
      }

      prev_lineno = pset.lineno;
      pset.lineno = 0;


      /* main loop to get queries and execute them */
!     while (successResult == EXIT_SUCCESS)
      {
          /*
           * Welcome code for Control-C
***************
*** 109,114 ****
--- 103,109 ----
              }

              cancel_pressed = false;
+             fflush(stdout);
          }

  #ifndef WIN32
***************
*** 118,132 ****

              if (pset.cur_cmd_interactive)
              {
!                 fputc('\n', stdout);
                  resetPQExpBuffer(query_buf);

                  /* reset parsing state */
!                 in_xcomment = false;
                  in_quote = 0;
                  paren_level = 0;
                  count_eof = 0;
                  slashCmdStatus = CMD_UNKNOWN;
              }
              else
              {
--- 113,128 ----

              if (pset.cur_cmd_interactive)
              {
!                 putc('\n', stdout);
                  resetPQExpBuffer(query_buf);

                  /* reset parsing state */
!                 in_xcomment = 0;
                  in_quote = 0;
                  paren_level = 0;
                  count_eof = 0;
                  slashCmdStatus = CMD_UNKNOWN;
+                 fflush(stdout);
              }
              else
              {
***************
*** 151,173 ****
              line = xstrdup(query_buf->data);
              resetPQExpBuffer(query_buf);
              /* reset parsing state since we are rescanning whole line */
!             in_xcomment = false;
              in_quote = 0;
              paren_level = 0;
              slashCmdStatus = CMD_UNKNOWN;
          }
-         else
-         {
-             fflush(stdout);
-
              /*
               * otherwise, set interactive prompt if necessary and get
               * another line
               */
!             if (pset.cur_cmd_interactive)
              {
                  int            prompt_status;

                  if (in_quote && in_quote == '\'')
                      prompt_status = PROMPT_SINGLEQUOTE;
                  else if (in_quote && in_quote == '"')
--- 147,167 ----
              line = xstrdup(query_buf->data);
              resetPQExpBuffer(query_buf);
              /* reset parsing state since we are rescanning whole line */
!             in_xcomment = 0;
              in_quote = 0;
              paren_level = 0;
              slashCmdStatus = CMD_UNKNOWN;
          }
              /*
               * otherwise, set interactive prompt if necessary and get
               * another line
               */
!         else if (pset.cur_cmd_interactive)
              {
                  int            prompt_status;

+             fflush(stdout);
+
                  if (in_quote && in_quote == '\'')
                      prompt_status = PROMPT_SINGLEQUOTE;
                  else if (in_quote && in_quote == '"')
***************
*** 185,191 ****
              }
              else
                  line = gets_fromFile(source);
-         }


          /* Setting this will not have effect until next line. */
--- 179,184 ----
***************
*** 203,252 ****
          {
              if (pset.cur_cmd_interactive)
              {
-                 bool        getout = true;
-
                  /* This tries to mimic bash's IGNOREEOF feature. */
!                 const char *val = GetVariable(pset.vars, "IGNOREEOF");
!
!                 if (val)
!                 {
!                     long int    maxeof;
!                     char       *endptr;
!
!                     if (*val == '\0')
!                         maxeof = 10;
!                     else
!                     {
!                         maxeof = strtol(val, &endptr, 0);
!                         if (*endptr != '\0')    /* string not valid as a
!                                                  * number */
!                             maxeof = 10;
!                     }
!
!                     if (count_eof++ != maxeof)
!                         getout = false; /* not quite there yet */
!                 }

!                 if (getout)
!                 {
!                     if (QUIET())
!                         putc('\n', stdout);
!                     else
!                         puts("\\q");
!                     break;
!                 }
!                 else
                  {
                      if (!QUIET())
                          printf(gettext("Use \"\\q\" to leave %s.\n"), pset.progname);
                      continue;
                  }
              }
-             else
- /* not interactive */
                  break;
          }
!         else
              count_eof = 0;

          pset.lineno++;
--- 196,216 ----
          {
              if (pset.cur_cmd_interactive)
              {
                  /* This tries to mimic bash's IGNOREEOF feature. */
!                 count_eof++;

!                 if (count_eof < GetVariableNum(pset.vars,"IGNOREEOF",0,10,false))
                  {
                      if (!QUIET())
                          printf(gettext("Use \"\\q\" to leave %s.\n"), pset.progname);
                      continue;
                  }
+
+                 puts(QUIET() ? "" : "\\q");
              }
                  break;
          }
!
              count_eof = 0;

          pset.lineno++;
***************
*** 259,266 ****
          }

          /* echo back if flag is set */
!         var = GetVariable(pset.vars, "ECHO");
!         if (!pset.cur_cmd_interactive && var && strcmp(var, "all") == 0)
              puts(line);
          fflush(stdout);

--- 223,229 ----
          }

          /* echo back if flag is set */
!         if (!pset.cur_cmd_interactive && VariableEquals(pset.vars, "ECHO", "all"))
              puts(line);
          fflush(stdout);

***************
*** 276,289 ****
  #define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i, pset.encoding))

          success = true;
!         for (i = 0, prevlen = 0, thislen = (len > 0) ? PQmblen(line, pset.encoding) : 0;
!              i < len;
!              ADVANCE_1)
          {
              /* was the previous character a backslash? */
!             bool        was_bslash = (i > 0 && line[i - prevlen] == '\\');
!
!             if (was_bslash)
                  bslash_count++;
              else
                  bslash_count = 0;
--- 239,251 ----
  #define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i, pset.encoding))

          success = true;
!         prevlen = 0;
!         thislen = ((len > 0) ? PQmblen(line, pset.encoding) : 0);
!
!         for (i = 0; (i < len) && (success || !die_on_error); ADVANCE_1)
          {
              /* was the previous character a backslash? */
!             if (i > 0 && line[i - prevlen] == '\\')
                  bslash_count++;
              else
                  bslash_count = 0;
***************
*** 308,337 ****
                      in_quote = 0;
              }

!             /* in extended comment? */
!             else if (in_xcomment)
!             {
!                 if (line[i] == '*' && line[i + thislen] == '/')
!                 {
!                     if (xcdepth > 0)
!                         xcdepth--;
!                     else
                      {
!                         in_xcomment = false;
                          ADVANCE_1;
                      }
-                 }
-                 else if (line[i] == '/' && line[i + thislen] == '*')
-                     xcdepth++;
-             }

!             /* start of extended comment? */
!             else if (line[i] == '/' && line[i + thislen] == '*')
              {
!                 xcdepth = 0;
!                 in_xcomment = true;
                  ADVANCE_1;
              }

              /* start of quote? */
              else if (line[i] == '\'' || line[i] == '"')
--- 270,293 ----
                      in_quote = 0;
              }

!             /* start of extended comment? */
!             else if (line[i] == '/' && line[i + thislen] == '*')
                      {
!                 in_xcomment++;
!                 if (in_xcomment == 1)
                          ADVANCE_1;
                      }

!             /* end of extended comment? */
!             else if (line[i] == '*' && line[i + thislen] == '/')
              {
!                 in_xcomment--;
!                 if (in_xcomment <= 0)
!                 {
!                     in_xcomment = 0;
                  ADVANCE_1;
              }
+             }

              /* start of quote? */
              else if (line[i] == '\'' || line[i] == '"')
***************
*** 353,359 ****

              /* colon -> substitute variable */
              /* we need to be on the watch for the '::' operator */
!             else if (line[i] == ':' && !was_bslash
                    && strspn(line + i + thislen, VALID_VARIABLE_CHARS) > 0
                       && !(prevlen > 0 && line[i - prevlen] == ':')
                  )
--- 309,315 ----

              /* colon -> substitute variable */
              /* we need to be on the watch for the '::' operator */
!             else if (line[i] == ':' && !bslash_count
                    && strspn(line + i + thislen, VALID_VARIABLE_CHARS) > 0
                       && !(prevlen > 0 && line[i - prevlen] == ':')
                  )
***************
*** 411,417 ****
              }

              /* semicolon? then send query */
!             else if (line[i] == ';' && !was_bslash && !paren_level)
              {
                  line[i] = '\0';
                  /* is there anything else on the line? */
--- 367,373 ----
              }

              /* semicolon? then send query */
!             else if (line[i] == ';' && !bslash_count && !paren_level)
              {
                  line[i] = '\0';
                  /* is there anything else on the line? */
***************
*** 442,448 ****
               * if you have a burning need to send a semicolon or colon to
               * the backend ...
               */
!             else if (was_bslash && (line[i] == ';' || line[i] == ':'))
              {
                  /* remove the backslash */
                  memmove(line + i - prevlen, line + i, len - i + 1);
--- 398,404 ----
               * if you have a burning need to send a semicolon or colon to
               * the backend ...
               */
!             else if (bslash_count && (line[i] == ';' || line[i] == ':'))
              {
                  /* remove the backslash */
                  memmove(line + i - prevlen, line + i, len - i + 1);
***************
*** 451,457 ****
              }

              /* backslash command */
!             else if (was_bslash)
              {
                  const char *end_of_cmd = NULL;

--- 407,413 ----
              }

              /* backslash command */
!             else if (bslash_count)
              {
                  const char *end_of_cmd = NULL;

***************
*** 499,513 ****
                      paren_level = 0;

                  /* process anything left after the backslash command */
!                 i += end_of_cmd - &line[i];
                  query_start = i;
              }
-
-
-             /* stop the script after error */
-             if (!success && die_on_error)
-                 break;
-
          }                        /* for (line) */


--- 455,463 ----
                      paren_level = 0;

                  /* process anything left after the backslash command */
!                 i = end_of_cmd - line;
                  query_start = i;
              }
          }                        /* for (line) */


***************
*** 533,557 ****
          if (query_buf->data[0] != '\0' && GetVariableBool(pset.vars, "SINGLELINE"))
          {
              success = SendQuery(query_buf->data);
!             slashCmdStatus = success ? CMD_SEND : CMD_ERROR;
              resetPQExpBuffer(previous_buf);
              appendPQExpBufferStr(previous_buf, query_buf->data);
              resetPQExpBuffer(query_buf);
          }

!
!         if (!success && die_on_error && !pset.cur_cmd_interactive)
          {
              successResult = EXIT_USER;
-             break;
-         }
-
-
          /* Have we lost the db connection? */
!         if (pset.db == NULL && !pset.cur_cmd_interactive)
!         {
              successResult = EXIT_BADCONN;
-             break;
          }
      }                            /* while !endoffile/session */

--- 483,501 ----
          if (query_buf->data[0] != '\0' && GetVariableBool(pset.vars, "SINGLELINE"))
          {
              success = SendQuery(query_buf->data);
!             slashCmdStatus = (success ? CMD_SEND : CMD_ERROR);
              resetPQExpBuffer(previous_buf);
              appendPQExpBufferStr(previous_buf, query_buf->data);
              resetPQExpBuffer(query_buf);
          }

!         if (!pset.cur_cmd_interactive)
          {
+             if (!success && die_on_error)
              successResult = EXIT_USER;
          /* Have we lost the db connection? */
!             else if (!pset.db)
              successResult = EXIT_BADCONN;
          }
      }                            /* while !endoffile/session */

Index: src/bin/psql/prompt.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/prompt.c,v
retrieving revision 1.22
diff -c -c -r1.22 prompt.c
*** src/bin/psql/prompt.c    25 Oct 2001 05:49:54 -0000    1.22
--- src/bin/psql/prompt.c    20 Mar 2003 06:42:26 -0000
***************
*** 69,85 ****
      char        buf[MAX_PROMPT_SIZE + 1];
      bool        esc = false;
      const char *p;
!     const char *prompt_string;

!     if (status == PROMPT_READY)
!         prompt_string = GetVariable(pset.vars, "PROMPT1");
!     else if (status == PROMPT_CONTINUE || status == PROMPT_SINGLEQUOTE || status == PROMPT_DOUBLEQUOTE || status ==
PROMPT_COMMENT|| status == PROMPT_PAREN) 
!         prompt_string = GetVariable(pset.vars, "PROMPT2");
!     else if (status == PROMPT_COPY)
!         prompt_string = GetVariable(pset.vars, "PROMPT3");
!     else
!         prompt_string = "? ";


      destination[0] = '\0';

--- 69,98 ----
      char        buf[MAX_PROMPT_SIZE + 1];
      bool        esc = false;
      const char *p;
!     const char *prompt_string = "? ";
!     const char *prompt_name = NULL;

!     switch (status)
!     {
!         case PROMPT_READY:
!             prompt_name = "PROMPT1";
!             break;
!
!         case PROMPT_CONTINUE:
!         case PROMPT_SINGLEQUOTE:
!         case PROMPT_DOUBLEQUOTE:
!         case PROMPT_COMMENT:
!         case PROMPT_PAREN:
!             prompt_name = "PROMPT2";
!             break;
!
!         case PROMPT_COPY:
!             prompt_name = "PROMPT3";
!             break;
!     }

+     if (prompt_name)
+       prompt_string = GetVariable(pset.vars, prompt_name);

      destination[0] = '\0';

***************
*** 92,112 ****
          {
              switch (*p)
              {
-                 case '%':
-                     strcpy(buf, "%");
-                     break;
-
                      /* Current database */
                  case '/':
                      if (pset.db)
                          strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE);
                      break;
                  case '~':
-                     {
-                         const char *var;
-
                          if (pset.db)
                          {
                              if (strcmp(PQdb(pset.db), PQuser(pset.db)) == 0 ||
                                  ((var = getenv("PGDATABASE")) && strcmp(var, PQdb(pset.db)) == 0))
                                  strcpy(buf, "~");
--- 105,119 ----
          {
              switch (*p)
              {
                      /* Current database */
                  case '/':
                      if (pset.db)
                          strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE);
                      break;
                  case '~':
                          if (pset.db)
                          {
+                         const char *var;
                              if (strcmp(PQdb(pset.db), PQuser(pset.db)) == 0 ||
                                  ((var = getenv("PGDATABASE")) && strcmp(var, PQdb(pset.db)) == 0))
                                  strcpy(buf, "~");
***************
*** 114,120 ****
                                  strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE);
                          }
                          break;
!                     }
                      /* DB server hostname (long/short) */
                  case 'M':
                  case 'm':
--- 121,127 ----
                                  strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE);
                          }
                          break;
!
                      /* DB server hostname (long/short) */
                  case 'M':
                  case 'm':
***************
*** 164,178 ****
                  case '7':
                  case '8':
                  case '9':
!                     {
!                         long int    l;
!                         char       *end;
!
!                         l = strtol(p, &end, 0);
!                         sprintf(buf, "%c", (unsigned char) l);
!                         p = end - 1;
                          break;
-                     }

                  case 'R':
                      switch (status)
--- 171,178 ----
                  case '7':
                  case '8':
                  case '9':
!                     *buf = parse_char(&p);
                          break;

                  case 'R':
                      switch (status)
Index: src/bin/psql/startup.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/startup.c,v
retrieving revision 1.71
diff -c -c -r1.71 startup.c
*** src/bin/psql/startup.c    18 Mar 2003 22:15:44 -0000    1.71
--- src/bin/psql/startup.c    20 Mar 2003 06:42:26 -0000
***************
*** 253,262 ****
       */
      else if (options.action == ACT_SINGLE_SLASH)
      {
!         const char *value;
!
!         if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all") == 0)
              puts(options.action_string);
          successResult = HandleSlashCmds(options.action_string, NULL, NULL, NULL) != CMD_ERROR
              ? EXIT_SUCCESS : EXIT_FAILURE;
      }
--- 253,261 ----
       */
      else if (options.action == ACT_SINGLE_SLASH)
      {
!         if (VariableEquals(pset.vars, "ECHO", "all"))
              puts(options.action_string);
+
          successResult = HandleSlashCmds(options.action_string, NULL, NULL, NULL) != CMD_ERROR
              ? EXIT_SUCCESS : EXIT_FAILURE;
      }
***************
*** 266,275 ****
       */
      else if (options.action == ACT_SINGLE_QUERY)
      {
!         const char *value;
!
!         if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all") == 0)
              puts(options.action_string);
          successResult = SendQuery(options.action_string)
              ? EXIT_SUCCESS : EXIT_FAILURE;
      }
--- 265,273 ----
       */
      else if (options.action == ACT_SINGLE_QUERY)
      {
!         if (VariableEquals(pset.vars, "ECHO", "all"))
              puts(options.action_string);
+
          successResult = SendQuery(options.action_string)
              ? EXIT_SUCCESS : EXIT_FAILURE;
      }
Index: src/bin/psql/variables.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/variables.c,v
retrieving revision 1.9
diff -c -c -r1.9 variables.c
*** src/bin/psql/variables.c    10 Feb 2001 02:31:28 -0000    1.9
--- src/bin/psql/variables.c    20 Mar 2003 06:42:26 -0000
***************
*** 68,73 ****
--- 68,141 ----
  }


+ bool
+ VariableEquals(VariableSpace space, const char name[], const char value[])
+ {
+     const char *var;
+     var = GetVariable(space, name);
+     return var && (strcmp(var, value) == 0);
+ }
+
+
+ int
+ GetVariableNum(VariableSpace space,
+                      const char name[],
+                     int defaultval,
+                     int faultval,
+                     bool allowtrail)
+ {
+     const char *var;
+     int result;
+
+     var = GetVariable(space, name);
+     if (!var)
+       result = defaultval;
+     else if (!var[0])
+       result = faultval;
+     else
+     {
+         char *end;
+         result = strtol(var, &end, 0);
+         if (!allowtrail && *end)
+           result = faultval;
+     }
+
+     return result;
+ }
+
+
+ int
+ SwitchVariable(VariableSpace space, const char name[], const char *opt, ...)
+ {
+     int result;
+     const char *var;
+
+     var = GetVariable(space, name);
+     if (var)
+     {
+         va_list args;
+         va_start(args, opt);
+         for (result=1; opt && (strcmp(var, opt) != 0); result++)
+             opt = va_arg(args,const char *);
+
+         if (!opt) result = var_notfound;
+         va_end(args);
+     }
+     else
+       result = var_notset;
+
+     return result;
+ }
+
+
+ void
+ PrintVariables(VariableSpace space)
+ {
+   struct _variable *ptr;
+   for (ptr = space->next; ptr; ptr = ptr->next)
+      printf("%s = '%s'\n", ptr->name, ptr->value);
+ }
+

  bool
  SetVariable(VariableSpace space, const char *name, const char *value)
Index: src/bin/psql/variables.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/variables.h,v
retrieving revision 1.10
diff -c -c -r1.10 variables.h
*** src/bin/psql/variables.h    5 Nov 2001 17:46:31 -0000    1.10
--- src/bin/psql/variables.h    20 Mar 2003 06:42:26 -0000
***************
*** 30,39 ****

  VariableSpace CreateVariableSpace(void);
  const char *GetVariable(VariableSpace space, const char *name);
! bool        GetVariableBool(VariableSpace space, const char *name);
! bool        SetVariable(VariableSpace space, const char *name, const char *value);
! bool        SetVariableBool(VariableSpace space, const char *name);
! bool        DeleteVariable(VariableSpace space, const char *name);
! void        DestroyVariableSpace(VariableSpace space);

  #endif   /* VARIABLES_H */
--- 30,62 ----

  VariableSpace CreateVariableSpace(void);
  const char *GetVariable(VariableSpace space, const char *name);
! bool    GetVariableBool(VariableSpace space, const char *name);
! bool    VariableEquals(VariableSpace space, const char name[], const char *opt);
!
! /* Read numeric variable, or defaultval if it is not set, or faultval if its
!  * value is not a valid numeric string.  If allowtrail is false, this will
!  * include the case where there are trailing characters after the number.
!  */
! int GetVariableNum(VariableSpace space,
!                          const char name[],
!                         int defaultval,
!                         int faultval,
!                         bool allowtrail);
!
!
! /* Find value of variable <name> among NULL-terminated list of alternative
!  * options.  Returns var_notset if the variable was not set, var_notfound if its
!  * value did not occur in the list of options, or the number of the matching
!  * option.  The first option is 1, the second is 2 and so on.
!  */
! enum { var_notset = 0, var_notfound = -1 };
! int     SwitchVariable(VariableSpace space, const char name[], const char *opt,...);
!
! void     PrintVariables(VariableSpace space);
!
! bool    SetVariable(VariableSpace space, const char *name, const char *value);
! bool    SetVariableBool(VariableSpace space, const char *name);
! bool    DeleteVariable(VariableSpace space, const char *name);
! void    DestroyVariableSpace(VariableSpace space);

  #endif   /* VARIABLES_H */

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: Dump ALTER TABLE/SET STORAGE in pg_dump
Next
From: Bruce Momjian
Date:
Subject: Re: hashed crosstab