Fix failure to think clearly about encoding conversion errors in COPY.
We can't regurgitate the unconverted string as I first thought, because the elog.c mechanisms will assume the error message data is in the server encoding and attempt a reverse conversion. Eventually it might be worth providing a short-circuit path to support this, but for now the simplest solution is to abandon trying to report back the line contents after a conversion failure. Per bug report from Sil Lee, 27-Oct-2004.
This commit is contained in:
parent
08510856a4
commit
f05cfd2c73
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.232 2004/09/13 20:06:27 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.233 2004/10/29 19:18:22 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1401,29 +1401,26 @@ copy_in_error_callback(void *arg)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* error is relevant to a particular line */
|
/* error is relevant to a particular line */
|
||||||
if (!line_buf_converted)
|
if (line_buf_converted ||
|
||||||
|
client_encoding == server_encoding)
|
||||||
{
|
{
|
||||||
/* didn't convert the encoding yet... */
|
limit_printout_length(&line_buf);
|
||||||
line_buf_converted = true;
|
errcontext("COPY %s, line %d: \"%s\"",
|
||||||
if (client_encoding != server_encoding)
|
copy_relname, copy_lineno,
|
||||||
{
|
line_buf.data);
|
||||||
char *cvt;
|
}
|
||||||
|
else
|
||||||
cvt = (char *) pg_client_to_server((unsigned char *) line_buf.data,
|
{
|
||||||
line_buf.len);
|
/*
|
||||||
if (cvt != line_buf.data)
|
* Here, the line buffer is still in a foreign encoding,
|
||||||
{
|
* and indeed it's quite likely that the error is precisely
|
||||||
/* transfer converted data back to line_buf */
|
* a failure to do encoding conversion (ie, bad data). We
|
||||||
line_buf.len = 0;
|
* dare not try to convert it, and at present there's no way
|
||||||
line_buf.data[0] = '\0';
|
* to regurgitate it without conversion. So we have to punt
|
||||||
appendBinaryStringInfo(&line_buf, cvt, strlen(cvt));
|
* and just report the line number.
|
||||||
}
|
*/
|
||||||
}
|
errcontext("COPY %s, line %d", copy_relname, copy_lineno);
|
||||||
}
|
}
|
||||||
limit_printout_length(&line_buf);
|
|
||||||
errcontext("COPY %s, line %d: \"%s\"",
|
|
||||||
copy_relname, copy_lineno,
|
|
||||||
line_buf.data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2175,16 +2172,7 @@ CopyReadLine(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Done reading the line. Convert it to server encoding.
|
* Done reading the line. Convert it to server encoding.
|
||||||
*
|
|
||||||
* Note: set line_buf_converted to true *before* attempting conversion;
|
|
||||||
* this prevents infinite recursion during error reporting should
|
|
||||||
* pg_client_to_server() issue an error, due to copy_in_error_callback
|
|
||||||
* again attempting the same conversion. We'll end up issuing the
|
|
||||||
* message without conversion, which is bad but better than nothing
|
|
||||||
* ...
|
|
||||||
*/
|
*/
|
||||||
line_buf_converted = true;
|
|
||||||
|
|
||||||
if (change_encoding)
|
if (change_encoding)
|
||||||
{
|
{
|
||||||
cvt = (char *) pg_client_to_server((unsigned char *) line_buf.data,
|
cvt = (char *) pg_client_to_server((unsigned char *) line_buf.data,
|
||||||
@ -2198,6 +2186,9 @@ CopyReadLine(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now it's safe to use the buffer in error messages */
|
||||||
|
line_buf_converted = true;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user