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

[email protected] (Peter Gordon)
Newsgroups perl.dbi.users
Message-ID <1282042500.2850.140.camel@qed>
Sorry about that - dsylexia is setting in.

https://bugzilla.mozilla.org/show_bug.cgi?id=481549



On Tue, 2010-08-17 at 11:44 +0100, Martin J. Evans wrote:
> 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
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.