[DBD::Pg] Fix client_encoding detection on pre-9.1 servers
dbdpg-commits-gENoVmVU/[email protected] Sun, 8 Feb 2015 01:57:32 +0000
| Newsgroups | gmane.comp.db.postgresql.dbdpg.cvs |
|---|---|
| Message-ID | <[email protected]> |
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