From 390cf3209b718382c0ec9793b714422189e9b68b Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 19 Apr 2011 12:17:13 -0400 Subject: [PATCH] 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. --- src/backend/commands/variable.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 5d0fbdfb40f..9efd20f2bcf 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -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;