Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

selectrow_hashref in DBI 1.32 doesn't always return a hashref

116 views
Skip to first unread message

Craig Sanders

unread,
Feb 13, 2003, 9:18:56 PM2/13/03
to dbi-...@perl.org
this seems to have changed since i installed DBI 1.32 (i upgraded from 1.30),
and is breaking some scripts which assume that it will always return a hash.

sometimes (when the query returns no rows), it returns the scalar "1" -
attempting to use that as a hashref causes the script to die (with "strict
refs" set - would cause strange errors without it)

the problem seems to be in _do_selectrow() in DBI.pm, which is also used
by selectrow_arrayref.

as a temporary workaround fix, i hacked _do_selectrow() so that it
always returns the appropriate reference.

like so:

sub _do_selectrow {
my ($method, $dbh, $stmt, $attr, @bind) = @_;
my $sth = ((ref $stmt) ? $stmt : $dbh->prepare($stmt, $attr))
or return;
$sth->execute(@bind)
or return;
my $row = $sth->$method()
and $sth->finish;
# temporary workaround fix. CAS 2003-02-14
if ($method =~ /ref/ && ! ref($row)) {
warn "***** _do_selectrow workaround";
$row = [] if ($method =~ /array/);
$row = {} if ($method =~ /hash/);
} ;
return $row;
}


i don't know the DBI code well enough to know whether this will have
other undesirable consequences, but it stops my scripts from dying until
a real fix is available.


craig

--
craig sanders <c...@taz.net.au>

Fabricati Diem, PVNC.
-- motto of the Ankh-Morpork City Watch

Tim Bunce

unread,
Feb 14, 2003, 6:05:19 AM2/14/03
to Craig Sanders, dbi-...@perl.org
Can you post an example script that calls selectrow_hashref and
demonstrates the problem?

Tim.

Tim Bunce

unread,
Feb 15, 2003, 7:56:09 AM2/15/03
to Craig Sanders, Tim Bunce, dbi-...@perl.org
On Sat, Feb 15, 2003 at 11:23:13AM +1100, Craig Sanders wrote:
> On Sat, Feb 15, 2003 at 10:51:14AM +1100, Craig Sanders wrote:

> > On Fri, Feb 14, 2003 at 11:05:19AM +0000, Tim Bunce wrote:
> > > Can you post an example script that calls selectrow_hashref and
> > > demonstrates the problem?
> >
> > the application is written in HTML::Mason, so all the stuff for opening
>
> the standalone version works OK (in that it doesn't die). for
> non-existent record id 100 (which causes the HTML::Mason version to
> die), the output is:

> so, it looks like in plain perl selectrow_hashref returns undef when the
> record doesn't exist, but in HTML::Mason it returns the scalar '1'.

Thanks. Dig deeper. I'd bet the code is doing something like

$row = $dbh->selectrow_hashref(...) || ...something...

where the ...something... is returning '1'.

Tim.

Craig Sanders

unread,
Feb 14, 2003, 6:51:14 PM2/14/03
to Tim Bunce, dbi-...@perl.org
On Fri, Feb 14, 2003 at 11:05:19AM +0000, Tim Bunce wrote:
> Can you post an example script that calls selectrow_hashref and
> demonstrates the problem?

the application is written in HTML::Mason, so all the stuff for opening
the database, session management, etc is absent from this test script.

(it's not my application, and not really my script. one of the
programmers complained that selectrow_hashref broke after the recent
upgrade to DBI 1.32. simple queries like the following worked in DBI
1.30, but broke in 1.32.)

test2.html:
---cut here---
my $sql = "SELECT * FROM linksdb WHERE id = ?";

foreach my $link_id (2, 4, 5, 6, 100, 101, 120) {
my $query_result = $dbh->selectrow_hashref($sql, undef, $link_id) ;

warn "QR: '$query_result'";
warn "QR->login: '" . $query_result->{login} . "'\n";
warn "QR->name : '" . $query_result->{name} . "'\n";
warn "QR->url : '" . $query_result->{url} . "'\n";
warn "QR->desc : '" . $query_result->{description} . "'\n";
};
---cut here---

link id numbers 2,4,5 & 6 exist in the database. 100, 101, and 120
don't.

all is fine until the script attempts to fetch the first non-existent
record (id 100). when that happens, selectrow_hashref returns the
scalar "1" rather than a hashref.

[Fri Feb 14 11:39:40 2003] null: QR: '1' at /home/mc2/public_html/test/test2.html line 6.

it then dies on line 7 with the attempt to dereference it.

Craig Sanders

unread,
Feb 14, 2003, 7:23:13 PM2/14/03
to Tim Bunce, dbi-...@perl.org
On Sat, Feb 15, 2003 at 10:51:14AM +1100, Craig Sanders wrote:
> On Fri, Feb 14, 2003 at 11:05:19AM +0000, Tim Bunce wrote:
> > Can you post an example script that calls selectrow_hashref and
> > demonstrates the problem?
>
> the application is written in HTML::Mason, so all the stuff for opening

this is actually significant. i just made a standalone perl script
which does exactly the same thing as the example i posted (i won't
include it here because the only difference is that it has the login &
password details for the postgres database).

the standalone version works OK (in that it doesn't die). for
non-existent record id 100 (which causes the HTML::Mason version to
die), the output is:

Use of uninitialized value in concatenation (.) or string at ./test2.pl line 26 (#1)
QR: '' at ./test2.pl line 26.
QR->login: ''
Use of uninitialized value in concatenation (.) or string at ./test2.pl line 28 (#1)
QR->name : ''
Use of uninitialized value in concatenation (.) or string at ./test2.pl line 29 (#1)
QR->url : ''
Use of uninitialized value in concatenation (.) or string at ./test2.pl line 30 (#1)
QR->desc : ''


so, it looks like in plain perl selectrow_hashref returns undef when the

record doesn't exist, but in HTML::Mason it returns the scalar '1'.

perl is 5.8.0
mason is 1.17
dbi is 1.32
postgres is 7.3.1

Craig Sanders

unread,
Feb 15, 2003, 7:56:24 PM2/15/03
to Tim Bunce, dbi-...@perl.org

doh!

yep, that was exactly what it was. i should have spotted that myself
before digging in to the internals of DBI.pm.

thanks,

0 new messages