Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re^2: DBD::Pg encodes Perlstring to UTF-8 bytes instead of WIN1252 regardless client encoding

by mje (Curate)
on Feb 04, 2014 at 11:06 UTC ( [id://1073366]=note: print w/replies, xml ) Need Help??


in reply to Re: DBD::Pg encodes Perlstring to UTF-8 bytes instead of WIN1252 regardless client encoding
in thread DBD::Pg encodes Perlstring to UTF-8 bytes instead of WIN1252 regardless client encoding

I don't use DBD::mysql these days but I do maintain DBD::ODBC and help maintain DBD::Oracle. I'm not aware of anything in DBI which "tampers" in any way with strings passed to the prepare or bind_param methods.

I've looked at DBD::mysql code and I cannot see anything that explains your "it's as if you actually passed". The original poster said his inserts were with the do method and no bound params and as far as I can see if he'd done that with DBD::mysql (instead of postgres) the string would have ended up in the mysql client API mysql_stmt_prepare untouched. Are you saying bound parameters work differently in DBD::mysql?

Other than some rather strange enbabling/disabling of SET NAMES in the code I can only find a few calls to sv_utf8_decode to decode UTF8 data received from mysql server and a test of:

if (SvUTF8(str)) SvUTF8_on(result);

in the quote method.

I'm really interested in this from the point of another DBD maintainer.

  • Comment on Re^2: DBD::Pg encodes Perlstring to UTF-8 bytes instead of WIN1252 regardless client encoding
  • Download Code

Replies are listed 'Best First'.
Re^3: DBD::Pg encodes Perlstring to UTF-8 bytes instead of WIN1252 regardless client encoding
by ikegami (Patriarch) on Mar 27, 2014 at 19:10 UTC

    I've looked at DBD::mysql code and I cannot see anything that explains your "it's as if you actually passed".

    Does it use SvPV(sv) without checking separate handling based on SvUTF8(sv)? It might do by using the default char* typemap (e.g. void xsfunc(char* s) { ... }).

    As you can see, the following C function is equivalent to that code:

    use strict; use warnings; use Test::More; use Encode qw( is_utf8 encode_utf8 ); use Inline C => <<'__EOC__'; void candidate(SV* sv) { dXSARGS; STRLEN len; char* buf = SvPV(sv, len); SP[0] = sv_2mortal(newSVpvn(buf, len)); XSRETURN(1); } __EOC__ sub baseline { is_utf8($_[0]) ? encode_utf8($_[0]) : $_[0] } sub _u { my ($s) = @_; utf8::upgrade($s); $s } sub _d { my ($s) = @_; utf8::downgrade($s); $s } sub printable { sprintf("%v04X", $_[0]) } my @tests = ( [ '00-7F', "a" ], [ '80-FF,UTF8=0', _d(chr(0xE9)) ], [ '80-FF,UTF8=1', _u(chr(0xE9)) ], [ '>FF', chr(0x2660) ], ); plan tests => 0+@tests; for (@tests) { my ($test_name, $input) = @$_; my $got = candidate($input); my $expected = baseline($input); #is($got, $expected, $test_name); is(printable($got), printable($expected), $test_name); }
    1..4 ok 1 - 00-7F ok 2 - 80-FF,UTF8=0 ok 3 - 80-FF,UTF8=1 ok 4 - >FF

    I'm really interested in this from the point of another DBD maintainer.

    Using the same configuration for all tests, can you roundtrip all of the strings mentioned earlier (as verified by is or eq)?

    my @tests = ( [ '00-7F', "a" ], [ '80-FF,UTF8=0', _d(chr(0xE9)) ], [ '80-FF,UTF8=1', _u(chr(0xE9)) ], [ '>FF', chr(0x2660) ], ); plan tests => 0+@tests; my $dbh = ... connect and setup as you wish ... my $sth = $dbh->prepare('SELECT ?'); for (@tests) { my ($test_name, $input) = @$_; $sth->execute($input) or die; my $row = $sth->fetch() or die; $sth->finish() or die if $row; my $got = $row->[0]; is(printable($got), printable($input), $test_name); }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1073366]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-19 22:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found