Author: timbo
Date: Mon Feb 11 04:56:30 2008
New Revision: 10719

Modified:
   dbi/trunk/Changes
   dbi/trunk/DBI.pm

Log:
Fixed fetchall_arrayref with $max_rows argument to pure-perl
+    to not error when fetching after all rows already fetched.
+    (Was fixed for compiled drivers back in DBI 1.31.)
+    Thanks to Mark Overmeer.
Fixed fast-fetch in fetchall_arrayref that was broken because
$max_rows was always defined.
Add note about RaiseError to batch fetchall_arrayref example.


Modified: dbi/trunk/Changes
==============================================================================
--- dbi/trunk/Changes   (original)
+++ dbi/trunk/Changes   Mon Feb 11 04:56:30 2008
@@ -40,7 +40,14 @@
 Call method on transport failure so transport can cleanup/reset if it wants
 Gofer: gearman - need to disable coallesing for non-idempotent requests
 
-=head2 Changes in DBI ...
+=head2 Changes in DBI 1.603
+
+  Fixed fetchall_arrayref with $max_rows argument to pure-perl
+    to not error when fetching after all rows already fetched.
+    (Was fixed for compiled drivers back in DBI 1.31.)
+    Thanks to Mark Overmeer.
+
+=head2 Changes in DBI 1.602 (svn rev 10706)  8th February 2008
 
   Fixed potential coredump if stack reallocated while calling back
     into perl from XS code. Thanks to John Gardiner Myers.

Modified: dbi/trunk/DBI.pm
==============================================================================
--- dbi/trunk/DBI.pm    (original)
+++ dbi/trunk/DBI.pm    Mon Feb 11 04:56:30 2008
@@ -1949,7 +1949,12 @@
 
     sub fetchall_arrayref {    # ALSO IN Driver.xst
        my ($sth, $slice, $max_rows) = @_;
-       $max_rows = -1 unless defined $max_rows;
+
+        # when batch fetching with $max_rows were very likely to try to
+        # fetch the 'next batch' after the previous batch returned
+        # <=$max_rows. So don't treat that as an error.
+        return undef if $max_rows and not $sth->{Active};
+
        my $mode = ref($slice) || 'ARRAY';
        my @rows;
        my $row;
@@ -1957,17 +1962,16 @@
            # we copy the array here because fetch (currently) always
            # returns the same array ref. XXX
            if ($slice && @$slice) {
-               $max_rows = -1 unless defined $max_rows;
+                $max_rows = -1 unless defined $max_rows;
                push @rows, [ @{$row}[ @$slice] ]
                    while($max_rows-- and $row = $sth->fetch);
            }
            elsif (defined $max_rows) {
-               $max_rows = -1 unless defined $max_rows;
                push @rows, [ @$row ]
                    while($max_rows-- and $row = $sth->fetch);
            }
            else {
-               push @rows, [ @$row ]          while($row = $sth->fetch);
+               push @rows, [ @$row ] while($row = $sth->fetch);
            }
        }
        elsif ($mode eq 'HASH') {
@@ -1975,6 +1979,8 @@
            if (keys %$slice) {
                my @o_keys = keys %$slice;
                my @i_keys = map { lc } keys %$slice;
+                # XXX this could be made faster by pre-binding a local hash
+                # using bind_columns and then copying it per row
                while ($max_rows-- and $row = 
$sth->fetchrow_hashref('NAME_lc')) {
                    my %hash;
                    @[EMAIL PROTECTED] = @[EMAIL PROTECTED];
@@ -5941,7 +5947,9 @@
 fetchall_arrayref() can then be called again to fetch more rows.
 This is especially useful when you need the better performance of
 fetchall_arrayref() but don't have enough memory to fetch and return
-all the rows in one go. Here's an example:
+all the rows in one go.
+
+Here's an example (assumes RaiseError is enabled):
 
   my $rows = []; # cache for batches of rows
   while( my $row = ( shift(@$rows) || # get row from cache, or reload cache:
@@ -5950,7 +5958,7 @@
     ...
   }
 
-That can be the fastest way to fetch and process lots of rows using the DBI,
+That I<might> be the fastest way to fetch and process lots of rows using the 
DBI,
 but it depends on the relative cost of method calls vs memory allocation.
 
 A standard C<while> loop with column binding is often faster because

Reply via email to