mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Revert COPY OUT to follow the pre-8.3 handling of ASCII control characters,
namely that \r, \n, \t, \b, \f, \v are dumped as those two-character representations rather than a backslash and the literal control character. I had made it do the other to save some code, but this was ill-advised, because dump files in which these characters appear literally are prone to newline mangling. Fortunately, doing it the old way should only cost a few more lines of code, and not slow down the copy loop materially. Per bug #3795 from Lou Duchez.
This commit is contained in:
parent
3b3251cb95
commit
a63b63ff96
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.289 2007/11/30 21:22:53 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.290 2007/12/03 00:03:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -3102,27 +3102,43 @@ CopyAttributeOutText(CopyState cstate, char *string)
|
|||||||
}
|
}
|
||||||
else if ((unsigned char) c < (unsigned char) 0x20)
|
else if ((unsigned char) c < (unsigned char) 0x20)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* \r and \n must be escaped, the others are traditional.
|
||||||
|
* We prefer to dump these using the C-like notation, rather
|
||||||
|
* than a backslash and the literal character, because it
|
||||||
|
* makes the dump file a bit more proof against Microsoftish
|
||||||
|
* data mangling.
|
||||||
|
*/
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* \r and \n must be escaped, the others are
|
|
||||||
* traditional
|
|
||||||
*/
|
|
||||||
case '\b':
|
case '\b':
|
||||||
|
c = 'b';
|
||||||
|
break;
|
||||||
case '\f':
|
case '\f':
|
||||||
|
c = 'f';
|
||||||
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
|
c = 'n';
|
||||||
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
|
c = 'r';
|
||||||
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
|
c = 't';
|
||||||
|
break;
|
||||||
case '\v':
|
case '\v':
|
||||||
DUMPSOFAR();
|
c = 'v';
|
||||||
CopySendChar(cstate, '\\');
|
|
||||||
start = ptr++; /* we include char in next run */
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* All ASCII control chars are length 1 */
|
/* All ASCII control chars are length 1 */
|
||||||
ptr++;
|
ptr++;
|
||||||
break;
|
continue; /* fall to end of loop */
|
||||||
}
|
}
|
||||||
|
/* if we get here, we need to convert the control char */
|
||||||
|
DUMPSOFAR();
|
||||||
|
CopySendChar(cstate, '\\');
|
||||||
|
CopySendChar(cstate, c);
|
||||||
|
start = ++ptr; /* do not include char in next run */
|
||||||
}
|
}
|
||||||
else if (IS_HIGHBIT_SET(c))
|
else if (IS_HIGHBIT_SET(c))
|
||||||
ptr += pg_encoding_mblen(cstate->client_encoding, ptr);
|
ptr += pg_encoding_mblen(cstate->client_encoding, ptr);
|
||||||
@ -3143,27 +3159,43 @@ CopyAttributeOutText(CopyState cstate, char *string)
|
|||||||
}
|
}
|
||||||
else if ((unsigned char) c < (unsigned char) 0x20)
|
else if ((unsigned char) c < (unsigned char) 0x20)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* \r and \n must be escaped, the others are traditional.
|
||||||
|
* We prefer to dump these using the C-like notation, rather
|
||||||
|
* than a backslash and the literal character, because it
|
||||||
|
* makes the dump file a bit more proof against Microsoftish
|
||||||
|
* data mangling.
|
||||||
|
*/
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* \r and \n must be escaped, the others are
|
|
||||||
* traditional
|
|
||||||
*/
|
|
||||||
case '\b':
|
case '\b':
|
||||||
|
c = 'b';
|
||||||
|
break;
|
||||||
case '\f':
|
case '\f':
|
||||||
|
c = 'f';
|
||||||
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
|
c = 'n';
|
||||||
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
|
c = 'r';
|
||||||
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
|
c = 't';
|
||||||
|
break;
|
||||||
case '\v':
|
case '\v':
|
||||||
DUMPSOFAR();
|
c = 'v';
|
||||||
CopySendChar(cstate, '\\');
|
|
||||||
start = ptr++; /* we include char in next run */
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* All ASCII control chars are length 1 */
|
/* All ASCII control chars are length 1 */
|
||||||
ptr++;
|
ptr++;
|
||||||
break;
|
continue; /* fall to end of loop */
|
||||||
}
|
}
|
||||||
|
/* if we get here, we need to convert the control char */
|
||||||
|
DUMPSOFAR();
|
||||||
|
CopySendChar(cstate, '\\');
|
||||||
|
CopySendChar(cstate, c);
|
||||||
|
start = ++ptr; /* do not include char in next run */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ptr++;
|
ptr++;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user