Subject: | missing error when a prepared statement with placeholders is executed with an empty bind |
Date: | Thu, 7 Jun 2018 17:39:18 +0200 |
To: | bug-DBI [...] rt.cpan.org |
From: | "Ruud H.G. van Tol" <ruud.vantol [...] booking.com> |
Missing error when a prepared statement with placeholders is executed
with an empty bind.
We now use this work-around:
use DBI;
use constant FAIL_ON_MYSQL_BUG_ABOUT_MISSING_ALL_PARAMETERS => 1;
BEGIN { # countering a DBD::mysql bug
if ( FAIL_ON_MYSQL_BUG_ABOUT_MISSING_ALL_PARAMETERS ) {
no warnings "redefine";
require DBD::mysql;
my $pa_key = "private_dbd_mysql_st_params";
my %orig;
for my $m (qw/ prepare bind_param execute /) {
$orig{ $m } = \&{"DBD::mysql::st::$m"}
or die qq{can't hook DBD::mysql::st::$m};
}
*DBD::mysql::st::prepare= sub {
my $sth= $_[0];
$sth->{ $pa_key } = []; # initialize storage
goto $orig{ prepare };
};
*DBD::mysql::st::bind_param= sub {
my $sth= $_[0];
$sth->{ $pa_key }[ $_[1] - 1 ] = undef; # occupy slot
goto $orig{ bind_param };
};
*DBD::mysql::st::execute= sub {
my $sth= $_[0];
if ( @_ == 1 # no execute-params
and my $want_num= $sth->FETCH("NUM_OF_PARAMS")
) { # must be a FETCH; may be undef
# see also $sth->{ParamValues}
my $have_num= @{ $sth->{ $pa_key } // [] };
if ( $have_num != $want_num ) {
my $error= "called with $have_num bind variables
when $want_num are needed (bug-fix)";
return $sth->set_err($DBI::stderr, $error);
}
}
goto $orig{ execute };
};
}
}
-- Greetings, Ruud