use strict; use warnings FATAL => 'all'; use DBI; use Test::More; use vars qw($test_dsn $test_user $test_password); use vars qw($COL_NULLABLE $COL_KEY); use lib 't', '.'; require 'lib.pl'; my $tb = Test::More->builder; binmode $tb->output, ":utf8"; binmode $tb->failure_output, ":utf8"; binmode $tb->todo_output, ":utf8"; my $dbh = DbiTestConnect($test_dsn, $test_user, $test_password, { RaiseError => 1, PrintError => 0, AutoCommit => 0 }); plan tests => 40 * 2; for my $mariadb_server_prepare (0, 1) { $dbh= DBI->connect("$test_dsn;mariadb_server_prepare=$mariadb_server_prepare;mariadb_server_prepare_disable_fallback=1", $test_user, $test_password, { RaiseError => 1, PrintError => 0, AutoCommit => 0 }); ok $dbh->do("DROP TABLE IF EXISTS dbd_mysql_t55utf8"); my $create =<do($create); my $unicode_str = "\N{U+0100}dam"; # Unicode "Adam" with a macron (internally stored as utf8) my $quoted_unicode_str = "'\N{U+0100}dam'"; my $blob = "\x{c4}\x{80}dam"; # UTF-8 representation of $unicode_str my $quoted_blob = "'\x{c4}\x{80}dam'"; my $unicode_str2 = "\x{c1}dam"; # Unicode "Adam" with a acute (internally stored as latin1) my $ascii_str = "?dam"; # ASCII representation of $unicode_str (and also $unicode_str2) my $latin1_str2 = "\x{c1}dam"; # Latin1 representation of $unicode_str2 (well, really same as $unicode_str2) my $blob2 = "\x{c3}\x{81}dam"; # UTF-8 representation of $unicode_str2 cmp_ok $dbh->quote($unicode_str), 'eq', $quoted_unicode_str, 'testing quoting of utf 8 string'; cmp_ok $dbh->quote($blob), 'eq', $quoted_blob, 'testing quoting of blob'; ok $dbh->do("SET SQL_MODE=''"), 'SET SQL_MODE=\'\''; # GeomFromText() is deprecated as of MySQL 5.7.6, use ST_GeomFromText() instead my $geomfromtext = $dbh->{mariadb_serverversion} >= 50706 ? 'ST_GeomFromText' : 'GeomFromText'; my $query = <prepare($query, { mariadb_server_prepare => 0 }) or die "$DBI::errstr"; ok $sth->bind_param(1, $unicode_str); ok $sth->bind_param(2, $blob, DBI::SQL_BINARY); ok $sth->bind_param(3, $unicode_str); ok $sth->bind_param(4, $unicode_str); ok $sth->bind_param(5, $unicode_str2); ok $sth->bind_param(6, $unicode_str); ok $sth->bind_param(7, $unicode_str2); ok $sth->execute() or die("Execute failed: ".$DBI::errstr); cmp_ok($dbh->{mariadb_warning_count}, '==', 1, 'got warning for INSERT') or do { diag("SHOW WARNINGS:"); diag($_->[2]) foreach $dbh->selectall_array("SHOW WARNINGS", { mariadb_server_prepare => 0 }); }; my (undef, undef, $warning) = $dbh->selectrow_array("SHOW WARNINGS", { mariadb_server_prepare => 0 }); like($warning, qr/^(?:Incorrect string value: '\\xC4\\x80dam'|Data truncated) for column (?:'ascii'|`.*`\.`.*`\.`ascii`) at row 1$/, 'warning is correct'); # AsBinary() is deprecated as of MySQL 5.7.6, use ST_AsBinary() instead my $asbinary = $dbh->{mariadb_serverversion} >= 50706 ? 'ST_AsBinary' : 'AsBinary'; $query = "SELECT name,bincol,$asbinary(shape), binutf, profile, str2, ascii, latin FROM dbd_mysql_t55utf8 LIMIT 1"; $sth = $dbh->prepare($query) or die "$DBI::errstr"; ok $sth->execute; my $ref; $ref = $sth->fetchrow_arrayref ; ok defined $ref, 'got data' or $ref = []; cmp_ok $ref->[0], 'eq', $unicode_str; cmp_ok $ref->[1], 'eq', $blob; cmp_ok $ref->[3], 'eq', $unicode_str; cmp_ok $ref->[4], 'eq', $unicode_str; cmp_ok $ref->[5], 'eq', $unicode_str2; cmp_ok $ref->[6], 'eq', $ascii_str; cmp_ok $ref->[7], 'eq', $latin1_str2; cmp_ok $ref->[1], 'eq', $blob, "compare $ref->[1] eq $blob"; my $prev_charset = $dbh->selectrow_array('SELECT @@character_set_results'); ok $dbh->do("SET character_set_results='latin1'"), "SET character_set_results='latin1'"; $ref = $dbh->selectrow_arrayref($query); ok defined $ref, 'got data' or $ref = []; cmp_ok $ref->[0], 'eq', $ascii_str, 'utf8 data are returned as latin1 when @@character_set_results is latin1'; cmp_ok $ref->[1], 'eq', $blob, 'blob is unchanged when @@character_set_results is latin1'; cmp_ok $ref->[3], 'eq', $ascii_str, 'utf8 data are returned as latin1 when @@character_set_results is latin1'; cmp_ok $ref->[4], 'eq', $ascii_str, 'utf8 data are returned as latin1 when @@character_set_results is latin1'; cmp_ok $ref->[5], 'eq', $latin1_str2, 'utf8 data are returned as latin1 when @@character_set_results is latin1'; cmp_ok $ref->[6], 'eq', $ascii_str, 'latin1 data are returned as latin1 when @@character_set_results is latin1'; cmp_ok $ref->[7], 'eq', $latin1_str2, 'latin1 data are returned as latin1 when @@character_set_results is latin1'; ok $sth = $dbh->prepare("SELECT 1 FROM dbd_mysql_t55utf8 WHERE bincol = ?"); ok !defined eval { $sth->bind_param(1, $unicode_str, DBI::SQL_BINARY) }; like $@, qr/^Wide character in /, ''; ok $dbh->do("SET character_set_results='$prev_charset'"), "SET character_set_results='$prev_charset'"; ok $dbh->do("DROP TABLE dbd_mysql_t55utf8"); ok $dbh->disconnect; }