aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/copy.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-10-29 19:18:22 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-10-29 19:18:22 +0000
commitf05cfd2c73af549c0f3035d499657b94ccf6005f (patch)
tree7415a1f56c5d6faac594f91b44f6a214e8dfd1b6 /src/backend/commands/copy.c
parent08510856a4b05b5d4bd609a8a9c362a81d3ed55a (diff)
downloadpostgresql-f05cfd2c73af549c0f3035d499657b94ccf6005f.tar.gz
postgresql-f05cfd2c73af549c0f3035d499657b94ccf6005f.zip
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.
Diffstat (limited to 'src/backend/commands/copy.c')
-rw-r--r--src/backend/commands/copy.c53
1 files changed, 22 insertions, 31 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 9c49001b27e..c2b2b205aa1 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -8,7 +8,7 @@
*
*
* 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
{
/* 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... */
- line_buf_converted = true;
- if (client_encoding != server_encoding)
- {
- char *cvt;
-
- cvt = (char *) pg_client_to_server((unsigned char *) line_buf.data,
- line_buf.len);
- if (cvt != line_buf.data)
- {
- /* transfer converted data back to line_buf */
- line_buf.len = 0;
- line_buf.data[0] = '\0';
- appendBinaryStringInfo(&line_buf, cvt, strlen(cvt));
- }
- }
+ limit_printout_length(&line_buf);
+ errcontext("COPY %s, line %d: \"%s\"",
+ copy_relname, copy_lineno,
+ line_buf.data);
+ }
+ else
+ {
+ /*
+ * Here, the line buffer is still in a foreign encoding,
+ * and indeed it's quite likely that the error is precisely
+ * a failure to do encoding conversion (ie, bad data). We
+ * dare not try to convert it, and at present there's no way
+ * to regurgitate it without conversion. So we have to punt
+ * 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.
- *
- * 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)
{
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;
}