Commit 390cf320 authored by Tom Lane's avatar Tom Lane

Refrain from canonicalizing a client_encoding setting of "UNICODE".

While "UTF8" is the correct name for this encoding, existing JDBC drivers
expect that if they send "UNICODE" it will read back the same way; they
fail with an opaque "Protocol error" complaint if not.  This will be fixed
in the 9.1 drivers, but until older drivers are no longer in use in the
wild, we'd better leave "UNICODE" alone.  Continue to canonicalize all
other inputs.  Per report from Steve Singer and subsequent discussion.
parent ca5a75fb
......@@ -759,12 +759,16 @@ bool
check_client_encoding(char **newval, void **extra, GucSource source)
{
int encoding;
const char *canonical_name;
/* Look up the encoding by name */
encoding = pg_valid_client_encoding(*newval);
if (encoding < 0)
return false;
/* Get the canonical name (no aliases, uniform case) */
canonical_name = pg_encoding_to_char(encoding);
/*
* If we are not within a transaction then PrepareClientEncoding will not
* be able to look up the necessary conversion procs. If we are still
......@@ -786,7 +790,7 @@ check_client_encoding(char **newval, void **extra, GucSource source)
/* Must be a genuine no-such-conversion problem */
GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
GUC_check_errdetail("Conversion between %s and %s is not supported.",
pg_encoding_to_char(encoding),
canonical_name,
GetDatabaseEncodingName());
}
else
......@@ -798,13 +802,27 @@ check_client_encoding(char **newval, void **extra, GucSource source)
}
/*
* Return the encoding's canonical name, and save its ID in *extra.
* Replace the user-supplied string with the encoding's canonical name.
* This gets rid of aliases and case-folding variations.
*
* XXX Although canonicalizing seems like a good idea in the abstract, it
* breaks pre-9.1 JDBC drivers, which expect that if they send "UNICODE"
* as the client_encoding setting then it will read back the same way.
* As a workaround, don't replace the string if it's "UNICODE". Remove
* that hack when pre-9.1 JDBC drivers are no longer in use.
*/
free(*newval);
*newval = strdup(pg_encoding_to_char(encoding));
if (!*newval)
return false;
if (strcmp(*newval, canonical_name) != 0 &&
strcmp(*newval, "UNICODE") != 0)
{
free(*newval);
*newval = strdup(canonical_name);
if (!*newval)
return false;
}
/*
* Save the encoding's ID in *extra, for use by assign_client_encoding.
*/
*extra = malloc(sizeof(int));
if (!*extra)
return false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment