Use of E'' in pg_dump - Mailing list pgsql-patches

From Bruce Momjian
Subject Use of E'' in pg_dump
Date
Msg-id 200507012106.j61L6JL01823@candle.pha.pa.us
Whole thread Raw
Responses Re: Use of E'' in pg_dump  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-patches
The following attached, applied patch uses E'' for strings containing
backslashes in pg_dump.  It does not modify COPY data output.

--
  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/pg_dump/dumputils.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v
retrieving revision 1.17
diff -c -c -r1.17 dumputils.c
*** src/bin/pg_dump/dumputils.c    30 Apr 2005 08:08:51 -0000    1.17
--- src/bin/pg_dump/dumputils.c    1 Jul 2005 20:57:27 -0000
***************
*** 111,116 ****
--- 111,137 ----
  void
  appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll)
  {
+     bool has_escapes = false;
+     const char *str2 = str;
+
+     while (*str2)
+     {
+         char        ch = *str2++;
+
+         if (ch == '\\' ||
+             ((unsigned char) ch < (unsigned char) ' ' &&
+              (escapeAll ||
+               (ch != '\t' && ch != '\n' && ch != '\v' &&
+                ch != '\f' && ch != '\r'))))
+         {
+             has_escapes = true;
+             break;
+         }
+     }
+
+     if (has_escapes)
+         appendPQExpBufferChar(buf, 'E');
+
      appendPQExpBufferChar(buf, '\'');
      while (*str)
      {
***************
*** 122,130 ****
              appendPQExpBufferChar(buf, ch);
          }
          else if ((unsigned char) ch < (unsigned char) ' ' &&
!                  (escapeAll
!                   || (ch != '\t' && ch != '\n' && ch != '\v' && ch != '\f' && ch != '\r')
!                   ))
          {
              /*
               * generate octal escape for control chars other than
--- 143,151 ----
              appendPQExpBufferChar(buf, ch);
          }
          else if ((unsigned char) ch < (unsigned char) ' ' &&
!                  (escapeAll ||
!                   (ch != '\t' && ch != '\n' && ch != '\v' &&
!                    ch != '\f' && ch != '\r')))
          {
              /*
               * generate octal escape for control chars other than
Index: src/bin/pg_dump/pg_backup_db.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v
retrieving revision 1.62
diff -c -c -r1.62 pg_backup_db.c
*** src/bin/pg_dump/pg_backup_db.c    21 Jun 2005 20:45:44 -0000    1.62
--- src/bin/pg_dump/pg_backup_db.c    1 Jul 2005 20:57:28 -0000
***************
*** 597,603 ****
                      }
                      else
                      {
-
                          if (qry[pos] == '\\')
                          {
                              if (AH->sqlparse.lastChar == '\\')
--- 597,602 ----
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.411
diff -c -c -r1.411 pg_dump.c
*** src/bin/pg_dump/pg_dump.c    30 Jun 2005 03:02:56 -0000    1.411
--- src/bin/pg_dump/pg_dump.c    1 Jul 2005 20:57:35 -0000
***************
*** 7767,7774 ****
      p = tginfo->tgargs;
      for (findx = 0; findx < tginfo->tgnargs; findx++)
      {
!         const char *s = p;

          for (;;)
          {
              p = strchr(p, '\\');
--- 7767,7775 ----
      p = tginfo->tgargs;
      for (findx = 0; findx < tginfo->tgnargs; findx++)
      {
!         const char *s = p, *s2 = p;

+         /* Set 'p' to end of arg string. marked by '\000' */
          for (;;)
          {
              p = strchr(p, '\\');
***************
*** 7781,7800 ****
                  exit_nicely();
              }
              p++;
!             if (*p == '\\')
              {
                  p++;
                  continue;
              }
!             if (p[0] == '0' && p[1] == '0' && p[2] == '0')
                  break;
          }
          p--;
          appendPQExpBufferChar(query, '\'');
          while (s < p)
          {
              if (*s == '\'')
!                 appendPQExpBufferChar(query, '\\');
              appendPQExpBufferChar(query, *s++);
          }
          appendPQExpBufferChar(query, '\'');
--- 7782,7810 ----
                  exit_nicely();
              }
              p++;
!             if (*p == '\\')        /* is it '\\'? */
              {
                  p++;
                  continue;
              }
!             if (p[0] == '0' && p[1] == '0' && p[2] == '0')  /* is it '\000'? */
                  break;
          }
          p--;
+
+         /* do we need E''? */
+         while (s2 < p)
+             if (*s2++ == '\\')
+             {
+                 appendPQExpBufferChar(query, 'E');
+                 break;
+             }
+
          appendPQExpBufferChar(query, '\'');
          while (s < p)
          {
              if (*s == '\'')
!                 appendPQExpBufferChar(query, '\'');
              appendPQExpBufferChar(query, *s++);
          }
          appendPQExpBufferChar(query, '\'');

pgsql-patches by date:

Previous
From: Heikki Linnakangas
Date:
Subject: Re: psql tab-completion for COMMIT/ROLLBACK PREPARED
Next
From: Stephen Frost
Date:
Subject: Roles - SET ROLE