* Tim Bunce via RT (bug-DBD-File@rt.cpan.org) [080209 21:37]:
Show quoted text> > I expect $sth->fetchall_arrayref to behave as
> > $sth->fetchall_arrayref(undef, undef)
> > and an <undef> number of rows as <all rows>
> > More like splice, or any queue. From empty you get nothing.
>
> You're changing the subject slightly. The original issue is whether this
> code should case a warning:
>
> while (1) {
> my $rows = $sth->fetchall_arrayref;
> $rows && @$rows or last;
> warn Dumper $rows;
> }
True. First, I detected the bug with row-count argument, then simplified
the situation into without arguments. Usually, it is better to file a bug
as simple as possible. In this case, it changed your opinion.
But apparently, this situation is designed to be non-orthogonal:
the behavior of fetchall_arrayref differs on the number of parameters
given, not on the content of the parameters. Use less parameters means
use more defaults.
Show quoted text> I believe it should. There's simply no point in putting a fetch*all* rows
> call into a loop like that. The DBI issues a warning because in 99.97364%
> of cases the warning reflects a problem with the logic of the application.
Might be true. But that is not a problem on its own: without error
message, people will see that they loop endlessly or get an empty
array on the second loop which results in a false.
Show quoted text> To address your point above, it's an error to try to fetch from a
> statement handle after you're already fetched all the rows. Always has
> been, always will.
Perl does not do this (I know I am not telling you something you don't
know). If I shift on an empty array, I do not get an error.
my @a = <>; # execute
while(1) { splice @a, 0, @a }
So, IMO your restriction is against Perl's common philosophy and
non-orthogonal... all to help an accidental abuse.
Show quoted text> An exception was made for fetchall_arrayref(..., $max_rows) because
> without it this code would almost always trigger an error:
>
> my $rows = []; # cache for batches of rows
> while( my $row = ( shift(@$rows) || # get row from cache, or reload cache:
> shift(@{$rows=$sth->fetchall_arrayref(undef,10_000)||[]}) )
> ) {
> ...
> }
I know this line from the man-page. It does not contain an error-check on
the fetch. I prefer:
while(1)
{ my $rows = $sth->fetchall_arrayref(undef, ROW_CACHE_SIZE);
die "not all records received: ".$sth->errstr
if $sth->err;
defined $rows && @$rows
or last;
foreach (@$rows) { ... }
}
4 understandable lines of code + check, instead of three very compact lines.
which also dies with
DBD::CSV::st fetchall_arrayref failed: Attempt to fetch row from a
Non-SELECT statement [for Statement "SELECT * FROM mytable"] at ./a line 26.
Show quoted text> Not that simple. That would also remove the error message that should be
> given for any single row fetch beyond the end of the result set.
my @a = 1..100;
$a[3000] returns undef
In my view, Perl modules should imitate behavior of perl core functionality,
if they can. Perl doesn't complain much.
--
Regards,
MarkOv
------------------------------------------------------------------------
Mark Overmeer MSc MARKOV Solutions
Mark@Overmeer.net solutions@overmeer.net
http://Mark.Overmeer.net http://solutions.overmeer.net