summaryrefslogtreecommitdiff
path: root/src/backend/utils/mb
diff options
context:
space:
mode:
authorItagaki Takahiro2011-02-21 05:08:04 +0000
committerItagaki Takahiro2011-02-21 05:32:40 +0000
commit3cba8240a195c4f323e3f934bfeab308434a9973 (patch)
tree39c4641db5d73fb2ecb30a2807845aff53f3714c /src/backend/utils/mb
parent48d25bac9f024f36b43cbba58778adf9ad0207c6 (diff)
Add ENCODING option to COPY TO/FROM and file_fdw.
File encodings can be specified separately from client encoding. If not specified, client encoding is used for backward compatibility. Cases when the encoding doesn't match client encoding are slower than matched cases because we don't have conversion procs for other encodings. Performance improvement would be be a future work. Original patch by Hitoshi Harada, and modified by me.
Diffstat (limited to 'src/backend/utils/mb')
-rw-r--r--src/backend/utils/mb/mbutils.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 5ee74f747d0..b8a2728e4f5 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -497,14 +497,25 @@ pg_encoding_max_length_sql(PG_FUNCTION_ARGS)
char *
pg_client_to_server(const char *s, int len)
{
+ Assert(ClientEncoding);
+
+ return pg_any_to_server(s, len, ClientEncoding->encoding);
+}
+
+/*
+ * convert any encoding to server encoding.
+ */
+char *
+pg_any_to_server(const char *s, int len, int encoding)
+{
Assert(DatabaseEncoding);
Assert(ClientEncoding);
if (len <= 0)
return (char *) s;
- if (ClientEncoding->encoding == DatabaseEncoding->encoding ||
- ClientEncoding->encoding == PG_SQL_ASCII)
+ if (encoding == DatabaseEncoding->encoding ||
+ encoding == PG_SQL_ASCII)
{
/*
* No conversion is needed, but we must still validate the data.
@@ -524,8 +535,8 @@ pg_client_to_server(const char *s, int len)
* to the parser but we have no way to convert it. We compromise by
* rejecting the data if it contains any non-ASCII characters.
*/
- if (PG_VALID_BE_ENCODING(ClientEncoding->encoding))
- (void) pg_verify_mbstr(ClientEncoding->encoding, s, len, false);
+ if (PG_VALID_BE_ENCODING(encoding))
+ (void) pg_verify_mbstr(encoding, s, len, false);
else
{
int i;
@@ -543,7 +554,11 @@ pg_client_to_server(const char *s, int len)
return (char *) s;
}
- return perform_default_encoding_conversion(s, len, true);
+ if (ClientEncoding->encoding == encoding)
+ return perform_default_encoding_conversion(s, len, true);
+ else
+ return (char *) pg_do_encoding_conversion(
+ (unsigned char *) s, len, encoding, DatabaseEncoding->encoding);
}
/*
@@ -552,18 +567,33 @@ pg_client_to_server(const char *s, int len)
char *
pg_server_to_client(const char *s, int len)
{
+ Assert(ClientEncoding);
+
+ return pg_any_to_server(s, len, ClientEncoding->encoding);
+}
+
+/*
+ * convert server encoding to any encoding.
+ */
+char *
+pg_server_to_any(const char *s, int len, int encoding)
+{
Assert(DatabaseEncoding);
Assert(ClientEncoding);
if (len <= 0)
return (char *) s;
- if (ClientEncoding->encoding == DatabaseEncoding->encoding ||
- ClientEncoding->encoding == PG_SQL_ASCII ||
+ if (encoding == DatabaseEncoding->encoding ||
+ encoding == PG_SQL_ASCII ||
DatabaseEncoding->encoding == PG_SQL_ASCII)
return (char *) s; /* assume data is valid */
- return perform_default_encoding_conversion(s, len, false);
+ if (ClientEncoding->encoding == encoding)
+ return perform_default_encoding_conversion(s, len, false);
+ else
+ return (char *) pg_do_encoding_conversion(
+ (unsigned char *) s, len, DatabaseEncoding->encoding, encoding);
}
/*