]> granicus.if.org Git - postgresql/commitdiff
Swap the order of testing for control characters and for column delimiter in
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 Dec 2007 16:45:22 +0000 (16:45 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 Dec 2007 16:45:22 +0000 (16:45 +0000)
CopyAttributeOutText(), so that control characters are converted to the
C-style escape sequences even if they happen to be equal to the column
delimiter (as is true by default for tab, for example).  Oversight in my
previous patch to restore pre-8.3 behavior of COPY OUT escaping.  Per report
from Tomas Szepe.

src/backend/commands/copy.c

index 55ecf0098d4ce504d3e3c9a9903eff14b680a56c..a1aefcaad84048cd0f7f071a93db6d731dd5d7de 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.290 2007/12/03 00:03:05 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.291 2007/12/27 16:45:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3094,13 +3094,7 @@ CopyAttributeOutText(CopyState cstate, char *string)
                start = ptr;
                while ((c = *ptr) != '\0')
                {
-                       if (c == '\\' || c == delimc)
-                       {
-                               DUMPSOFAR();
-                               CopySendChar(cstate, '\\');
-                               start = ptr++;  /* we include char in next run */
-                       }
-                       else if ((unsigned char) c < (unsigned char) 0x20)
+                       if ((unsigned char) c < (unsigned char) 0x20)
                        {
                                /*
                                 * \r and \n must be escaped, the others are traditional.
@@ -3130,6 +3124,9 @@ CopyAttributeOutText(CopyState cstate, char *string)
                                                c = 'v';
                                                break;
                                        default:
+                                               /* If it's the delimiter, must backslash it */
+                                               if (c == delimc)
+                                                       break;
                                                /* All ASCII control chars are length 1 */
                                                ptr++;
                                                continue;               /* fall to end of loop */
@@ -3140,6 +3137,12 @@ CopyAttributeOutText(CopyState cstate, char *string)
                                CopySendChar(cstate, c);
                                start = ++ptr;                  /* do not include char in next run */
                        }
+                       else if (c == '\\' || c == delimc)
+                       {
+                               DUMPSOFAR();
+                               CopySendChar(cstate, '\\');
+                               start = ptr++;  /* we include char in next run */
+                       }
                        else if (IS_HIGHBIT_SET(c))
                                ptr += pg_encoding_mblen(cstate->client_encoding, ptr);
                        else
@@ -3151,13 +3154,7 @@ CopyAttributeOutText(CopyState cstate, char *string)
                start = ptr;
                while ((c = *ptr) != '\0')
                {
-                       if (c == '\\' || c == delimc)
-                       {
-                               DUMPSOFAR();
-                               CopySendChar(cstate, '\\');
-                               start = ptr++;  /* we include char in next run */
-                       }
-                       else if ((unsigned char) c < (unsigned char) 0x20)
+                       if ((unsigned char) c < (unsigned char) 0x20)
                        {
                                /*
                                 * \r and \n must be escaped, the others are traditional.
@@ -3187,6 +3184,9 @@ CopyAttributeOutText(CopyState cstate, char *string)
                                                c = 'v';
                                                break;
                                        default:
+                                               /* If it's the delimiter, must backslash it */
+                                               if (c == delimc)
+                                                       break;
                                                /* All ASCII control chars are length 1 */
                                                ptr++;
                                                continue;               /* fall to end of loop */
@@ -3197,6 +3197,12 @@ CopyAttributeOutText(CopyState cstate, char *string)
                                CopySendChar(cstate, c);
                                start = ++ptr;                  /* do not include char in next run */
                        }
+                       else if (c == '\\' || c == delimc)
+                       {
+                               DUMPSOFAR();
+                               CopySendChar(cstate, '\\');
+                               start = ptr++;  /* we include char in next run */
+                       }
                        else
                                ptr++;
                }