Hi,

I've just received a bug report for a regression in the way ping works
(took over 3 years for someone to notice) in DBD::ODBC. If the
connection handle is not connected when a ping it done you get:

DBD::ODBC::db ping failed: Cannot allocate statement when disconnected
from the database at -e line 1.

I've identified why and it is because DBD::ODBC now checks the
connection handle is active before allocating a statement handle (it
didn't before). I wanted to change the ping method in ODBC.pm to wrap
the test in an eval like this:

sub ping {
    my $dbh = shift;
    my $state = undef;

    my ($catalog, $schema, $table, $type);

    $catalog = "";
    $schema = "";
    $table = "NOXXTABLE";
    $type = "";

    my $evalret = eval {
        local $dbh->{RaiseError} = 0;
        local $dbh->{PrintError} = 0;

        # create a "blank" statement handle
        # the following is what fails if $dbh is not connected
        my $sth = DBI::_new_sth($dbh, { 'Statement' => "SQLTables_PING" });
        return 1 if !$sth;

        DBD::ODBC::st::_tables($dbh,$sth, $catalog, $schema, $table, $type)
              or return 1;
        $sth->finish;
        return 0;
    };
    if ($evalret == 0) {
        return 1;
    } else {
        return 0;
    }
}

as DBD::ODBC's dbdimp.c does the following if the connection handle is
not active when allocating a statement handle:

if (!DBIc_ACTIVE(imp_dbh)) {
    DBIh_SET_ERR_CHAR(
      h, imp_xxh, Nullch, 1,
      "Cannot allocate statement when disconnected from the database",
      "08003", Nullch);
    return 0;
}

However, the local does not work and the error is still printed.
Removing local from $dbh->{PrintError} works.

Any idea what I'm doing wrong here?

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com

Reply via email to