Committed by =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <[email protected]>
Fix client_encoding detection on pre-9.1 servers
Before 9.1 the client_encoding provided in the connection parameter was
not normalised, so we need to do that ourselves.
This fixes the tests on SQL_ASCII databases, as well, so we can revert
the commits that disabled them (1f3ed13 and 53df98c).
---
dbdimp.c | 28 ++++++++++++++++++++++------
t/12placeholders.t | 4 ++--
t/30unicode.t | 1 -
3 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/dbdimp.c b/dbdimp.c
index 6a64487..2dee5d4 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -84,6 +84,7 @@ static int pg_st_deallocate_statement(pTHX_ SV *sth,
imp_sth_t *imp_sth);
static PGTransactionStatusType pg_db_txn_status (pTHX_ imp_dbh_t *imp_dbh);
static int pg_db_start_txn (pTHX_ SV *dbh, imp_dbh_t *imp_dbh);
static int handle_old_async(pTHX_ SV * handle, imp_dbh_t * imp_dbh, const int
asyncflag);
+static void pg_db_detect_client_encoding_utf8(pTHX_ imp_dbh_t *imp_dbh);
/* ================================================================== */
void dbd_init (dbistate_t *dbistate)
@@ -224,9 +225,7 @@ int dbd_db_login6 (SV * dbh, imp_dbh_t * imp_dbh, char *
dbname, char * uid, cha
}
}
- imp_dbh->client_encoding_utf8 =
- (0 == strncmp(PQparameterStatus(imp_dbh->conn,
"client_encoding"), "UTF8", 4))
- ? DBDPG_TRUE : DBDPG_FALSE;
+ pg_db_detect_client_encoding_utf8(aTHX_ imp_dbh);
/* If the client_encoding is UTF8, flip the utf8 flag until convinced
otherwise */
imp_dbh->pg_utf8_flag = imp_dbh->client_encoding_utf8;
@@ -928,9 +927,7 @@ int dbd_db_STORE_attrib (SV * dbh, imp_dbh_t * imp_dbh, SV
* keysv, SV * valuesv
}
/* Do The Right Thing */
else if (-1 == imp_dbh->pg_enable_utf8) {
- imp_dbh->client_encoding_utf8 =
- (0 ==
strncmp(PQparameterStatus(imp_dbh->conn, "client_encoding"), "UTF8", 4))
- ? DBDPG_TRUE : DBDPG_FALSE;
+ pg_db_detect_client_encoding_utf8(aTHX_
imp_dbh);
imp_dbh->pg_enable_utf8 = -1;
imp_dbh->pg_utf8_flag =
imp_dbh->client_encoding_utf8;
}
@@ -2952,6 +2949,25 @@ SV * pg_rightgraded_sv(pTHX_ SV *input, bool utf8) {
return utf8 ? pg_upgraded_sv(aTHX_ input) : pg_downgraded_sv(aTHX_
input);
}
+static void pg_db_detect_client_encoding_utf8(pTHX_ imp_dbh_t *imp_dbh) {
+ char *clean_encoding;
+ int i, j;
+ const char * const client_encoding =
+ PQparameterStatus(imp_dbh->conn, "client_encoding");
+ STRLEN len = strlen(client_encoding);
+ Newx(clean_encoding, len + 1, char);
+ for (i = 0, j = 0; i < len; i++) {
+ const char c = toLOWER(client_encoding[i]);
+ if (isALPHANUMERIC_A(c))
+ clean_encoding[j++] = c;
+ };
+ clean_encoding[j] = '\0';
+ imp_dbh->client_encoding_utf8 =
+ (strnEQ(clean_encoding, "utf8", 4) || strnEQ(clean_encoding,
"unicode", 8))
+ ? DBDPG_TRUE : DBDPG_FALSE;
+ Safefree(clean_encoding);
+}
+
/* ================================================================== */
int pg_quickexec (SV * dbh, const char * sql, const int asyncflag)
{
diff --git a/t/12placeholders.t b/t/12placeholders.t
index a470c76..548cd19 100644
--- a/t/12placeholders.t
+++ b/t/12placeholders.t
@@ -657,8 +657,8 @@ for my $char (qw{0 9 A Z a z}) { ## six letters
SKIP: {
my $server_encoding = $dbh->selectrow_array('SHOW server_encoding');
- skip "Cannot test non-ascii dollar quotes with
server_encoding='$server_encoding' (need UTF8)", 3,
- unless $server_encoding =~ /UTF8/;
+ skip "Cannot test non-ascii dollar quotes with
server_encoding='$server_encoding' (need UTF8 or SQL_ASCII)", 3,
+ unless $server_encoding =~ /\A(?:UTF8|SQL_ASCII)\z/;
for my $ident (qq{\x{5317}}, qq{abc\x{5317}}, qq{_cde\x{5317}}) { ##
hi-bit chars
eval {
diff --git a/t/30unicode.t b/t/30unicode.t
index 2d23c47..aa993b6 100644
--- a/t/30unicode.t
+++ b/t/30unicode.t
@@ -58,7 +58,6 @@ foreach (
my %ranges = (
UTF8 => qr/.*/,
LATIN1 => qr/\A(?:ascii|latin 1 range)\z/,
- SQL_ASCII => qr/nada/,
);
foreach (@tests) {
--
1.8.4