"FREE ERROR BIND!" on stderr running DBD::mysql

"FREE ERROR BIND!" on stderr running DBD::mysql

am 06.01.2006 14:19:11 von Martin.Evans

Hi,

I colleague of mine has been briefly using DBD::mysql and was getting
a lot of "FREE ERROR BIND!" messages appearing on stderr. I was asked
to take a look and I've reproduced this with the following code
running against DBD::mysql 3.0002_4:

use DBI;
# DBI 1.50
# perl, v5.8.7 built for i686-linux
# mysql 5.0.15
#
my $dbh = DBI->connect('dbi:mysql:database=martin;host=localhost;',
'xxx', 'yyy');
$dbh->do(q/drop table if exists bindissue/);
$dbh->do(q/create table bindissue (a int)/);
my $sql = q/select a from bind where a = ?/;
my @data = $dbh->selectrow_array($sql, undef, 1);

which when run produces:

bash-2.05$ ./bind2.pl
FREE ERROR BIND!bash-2.05$

I presume because the result-set is empty.

This seems to be due to finish in the driver being called twice. I'm
not overly familiar with DBD::mysql but commenting out the finish call
(in dbd_st_fetch) below makes the problem go away:

if ((rc= mysql_stmt_fetch(imp_sth->stmt)))
{
if (rc == 1)
do_error(sth, mysql_stmt_errno(imp_sth->stmt),
mysql_stmt_error(imp_sth->stmt));

if (rc == 100)
{
/* Update row_num to affected_rows value */
imp_sth->row_num= mysql_stmt_affected_rows(imp_sth->stmt);
imp_sth->fetch_done=1;
}
/* MJE
if (!DBIc_COMPAT(imp_sth))
dbd_st_finish(sth, imp_sth);
*/

return Nullav;
}

May be the finish is required if rc == 1 but I've not got the time
right now to look into it. Perhaps someone who knows DBD::mysql better
might want to take a look (I can supply any other info on versions etc
if it helps).

As an aside, what exactly does DBIc_COMPAT do? The DBI::DBD document
refers to its use with "FOR AN OLD PERL INTERFACE" but the reason
was not clear to me.

Martin
--
Martin J. Evans
Easysoft Ltd, UK
Development

Re: "FREE ERROR BIND!" on stderr running DBD::mysql

am 06.01.2006 19:04:25 von Tim.Bunce

On Fri, Jan 06, 2006 at 01:19:11PM -0000, Martin J. Evans wrote:
>
> This seems to be due to finish in the driver being called twice. I'm
> not overly familiar with DBD::mysql but commenting out the finish call
> (in dbd_st_fetch) below makes the problem go away:
>
> if ((rc= mysql_stmt_fetch(imp_sth->stmt)))
> {
> if (rc == 1)
> do_error(sth, mysql_stmt_errno(imp_sth->stmt),
> mysql_stmt_error(imp_sth->stmt));
>
> if (rc == 100)
> {
> /* Update row_num to affected_rows value */
> imp_sth->row_num= mysql_stmt_affected_rows(imp_sth->stmt);
> imp_sth->fetch_done=1;
> }
> /* MJE
> if (!DBIc_COMPAT(imp_sth))
> dbd_st_finish(sth, imp_sth);
> */
>
> return Nullav;
> }
>
> May be the finish is required if rc == 1 but I've not got the time
> right now to look into it. Perhaps someone who knows DBD::mysql better
> might want to take a look (I can supply any other info on versions etc
> if it helps).
>
> As an aside, what exactly does DBIc_COMPAT do? The DBI::DBD document
> refers to its use with "FOR AN OLD PERL INTERFACE" but the reason
> was not clear to me.

It stems from the days of perl4 db interfaces (oraperl, sybperl etc).
Many drivers, such as DBD::Oracle, shipped with modules that provided
backwards compatibility with the old perl4 APIs (ie Oraperl).

Setting $sth->{Compat} = 1 will make DBIc_COMPAT(imp_sth) true.
So that gives you a pure-perl workaround.

Tim.

p.s. I've no idea why it's used in DBD::mysql in this way.