diff --git a/dbdimp.c b/dbdimp.c index 39db0336..525dcf80 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -4209,6 +4209,23 @@ int dbd_bind_ph(SV *sth, imp_sth_t *imp_sth, SV *param, SV *value, if (param_num <= 0 || param_num > DBIc_NUM_PARAMS(imp_sth)) { + if (!looks_like_number(param)) + { + STRLEN len; + char *paramstring; + paramstring = SvPV(param, len); + if(paramstring[len] == 0 && strlen(paramstring) == len) + { + do_error(sth, JW_ERR_ILLEGAL_PARAM_NUM, form("named parameters are unsupported: %s", paramstring), NULL); + return FALSE; + } + else + { + do_error(sth, JW_ERR_ILLEGAL_PARAM_NUM, " could not be coerced to a C string", NULL); + return FALSE; + } + } + do_error(sth, JW_ERR_ILLEGAL_PARAM_NUM, "Illegal parameter number", NULL); return FALSE; } diff --git a/lib/DBD/mysql.pm b/lib/DBD/mysql.pm index e22942b8..171e2dcd 100644 --- a/lib/DBD/mysql.pm +++ b/lib/DBD/mysql.pm @@ -1725,6 +1725,10 @@ parameter value and C the statement again, with other values unchanged. The attribute remains properly populated after the C method is called, with the values from the last execution. +MySQL does not support named place holders in C. If a +string is passed to C as the parameter index then a +"named parameters are unsupported" error is reported. + =item mysql_gtids Returns GTID(s) if GTID session tracking is ensabled in the server via diff --git a/t/45bindnamedparam_error.t b/t/45bindnamedparam_error.t new file mode 100644 index 00000000..8cbcd6f8 --- /dev/null +++ b/t/45bindnamedparam_error.t @@ -0,0 +1,53 @@ +use strict; +use warnings; + +use Test::More; +use DBI; +use vars qw($test_dsn $test_user $test_password); +use lib 't', '.'; +require 'lib.pl'; + +my $dbh; +eval {$dbh = DBI->connect($test_dsn, $test_user, $test_password, + { RaiseError => 1, AutoCommit => 1}) or ServerError();}; + +if ($@) { + plan skip_all => "no database connection"; +} +plan tests => 11; + +SKIP: { + skip 'SET @@auto_increment_offset needs MySQL >= 5.0.2', 2 unless $dbh->{mysql_serverversion} >= 50002; + ok $dbh->do('SET @@auto_increment_offset = 1'); + ok $dbh->do('SET @@auto_increment_increment = 1'); +} + +my $create= <do($create), "create table dbd_mysql_t45bindnamedparam"; + +ok $dbh->do("INSERT INTO dbd_mysql_t45bindnamedparam VALUES(NULL, 1)"), "insert into dbd_mysql_t45bindnamedparam (null, 1)"; + +my $rows; +ok ($rows= $dbh->selectall_arrayref("SELECT * FROM dbd_mysql_t45bindnamedparam")); + +is $rows->[0][1], 1, "\$rows->[0][1] == 1"; + +ok (my $sth = $dbh->prepare("SELECT * FROM dbd_mysql_t45bindnamedparam WHERE num = :num")); + +$dbh->{PrintError} = 0; +$dbh->{PrintWarn} = 0; +eval {($sth->bind_param(":num", 1, SQL_INTEGER()));}; +$dbh->{PrintError} = 1; +$dbh->{PrintWarn} = 1; +ok defined($DBI::errstr); + +like($DBI::errstr, qr/named parameters are unsupported/, 'bind_param reports exepcted error with named parameter'); + +ok ($sth->finish()); + +ok ($dbh->disconnect());