Re: selectall_arrayref returns ref to DBI and not an array ref

[email protected] ("Martin J. Evans")
Newsgroups perl.dbi.users
Organization Easysoft Limited
Message-ID <[email protected]>
On 17/08/10 10:47, Peter Gordon wrote:
> 
> I am trying to fix a problem in Bugzilla which has been open for more
> than a year,

Bugzilla shows VERIFIED FIXED at the moment.

> and which seems to be related to DBI, and I was hoping 
> that you could give me some direction in trying to solve the problem. On
> my site the problem is totally repeatable. I am using Perl 5.8.8,
> DBI-1.613_71. 

What DBD and version are you using?

> In short: on one line a variable is a reference to an array, and,
> directly after a return statement, the value is no longer an array, but
> a scalar
> having a reference to DBI. So it looks like something is
> changing/corrupting the Perl stack. Since Driver.xst and Perl.xsi change
> the stack it seems
> that that are likely to be causing the problem.

Strange.

> The bug in Bugzilla is:
> 
> https://bugzilla.mozilla.org/show_bug.cgi?id=481459

This bugzilla does not seem to match your description.

> 
> The code that seems to be causing the problem is:
> 
> my $objects = $dbh->selectall_arrayref($sql, {Slice=>{}}, @untainted);
> 
> For a given $sql and a given @untainted, the $objects returned is not 
> an array but a reference to DBI::db=HASH

Have you got RaiseError set?

What, if anything is in $dbh->err after the problem return?

> When I step through the code, selectall_arrayref works correctly until 
> the final return statement. Before the return statement, the type is an 
> array, and directly afterwards, it is a DBI::db=HASH.
> 
> The sql statement is:
> 
> SELECT id,value,product_id FROM versions WHERE  id IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
> ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
> ,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
> ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
> ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
> ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
> ,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
> ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
> ,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)    ORDER BY id
> 
> and the @untainted array is an equivalent number of small integers.
> 
> For a smaller or larger number of variables selectall_arrayref is working correctly. 
> 
> I changed the calling routine so that when an error was detected, the code was run again. On second and consecutive times the 
> code worked correctly.
> 
> I am prepared to debug the problem if someone could help.
> 
> Peter
> 
> 

Can you reproduce this in a small script outside of bugzilla Perl?

I tried mimicking what it looks like you are doing (mostly guess work) with DBD::ODBC and the latest DBI and found no problem:

use DBI;
use strict;

my $h = DBI->connect('dbi:ODBC:baugi','sa','easysoft');

eval {$h->do(q/drop table mje/);};

$h->do(q/create table mje (id integer, value varchar(200), product_id integer)/);

my $max = 1000;

$h->begin_work;
my $s = $h->prepare(q/insert into mje values(?,?,?)/);
foreach my $loop(1..$max) {
    $s->execute($loop, 'fred', $loop);
}
$h->commit;


foreach my $loop(1..($max+1)) { # last one won't match
    my @bound;
    push @bound, $_ foreach (1..$loop);

    my $sql = q/select id, value, product_id from mje where id in (/ .
        join(",", (map {'?'} @bound)) . ') order by id';
    my $x = $h->selectall_arrayref($sql, {Slice=>{}}, @bound);
    if (ref($x) ne 'ARRAY') {
        print "$loop\n";
    }
}
$h->disconnect;

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.