(DBI 1.604, DBD::ODBC 1.15, WinXP, AS 5.8.8)
I'm trying to test cancel of long running queries
via DBD::ODBC (using psqlodbc driver). I've written
a small proxy which injects 10+ second delays in
delivery of queries from client to server. And I've
managed to get SIGINT signals delivered to my app.
But it appears that DBD::ODBC doesn't appear to
believe the stmt handle is active when I cancel it.
I hacked DBD::ODBC's dbdimp.c:odbc_cancel() to
add printf's on entry, if no stmt is active,
or if SQLCancel fails. When I run the test and
hit ctrl-C, odbc_cancel() does get called, *but*
it reports no active statement.
So I commented out the Active test in odbc_cancel(),
and then everything works as expected.
Is this a known sequencing problem ? Is Active not getting
set until the rows start returning ? If so, shouldn't it get
set immediately upon calling SQLExecute ? I'm very certain the
query is still pending in the proxy when I hit ctrl-C, so
no rows have yet been returned. I turned on max tracing, but
I don't see any setting/clearing of Active included in the
traces.
My small sample app follows.
Any help much appreciated,
Dean Arnold
use DBI;
use strict;
use warnings;
#
# allow signals anytime !!VERY DANGEROUS!!
#
$ENV{PERL_SIGNALS} = 'unsafe';
my $dsn = scalar @ARGV ? shift @ARGV : 'PostgreSQL30';
my $dbh = DBI->connect("dbi:ODBC:$dsn", undef, undef,
{ RaiseError => 0}) or die $DBI::errstr;
$| = 1;
my $cancelled;
my $sth = $dbh->prepare('select * from perl_dbi_test') or die $dbh->errstr;
$SIG{INT} = sub {
print "You cancelled.\n";
print "Not cancelled.\n" unless $sth->cancel();
$cancelled = 1;
};
print "Executing...\n";
my $rc = $sth->execute;
print "execute() done rc $rc, fetching rows\n";
die "Didn't cancel!\n" if $rc;
print "Cancelled, error is ", $sth->errstr, "\n" if $cancelled;
$dbh->disconnect();