Stop instantiating a cursor on single() use
Peter Rabbitson [Wed, 24 Apr 2013 03:23:43 +0000 (05:23 +0200)]
This minor pessimization snuck in all the way back in 4e9fc3f3.
I am actually not entirely sure whether this isn't a bug - after
all this way Cursor::Cached and friends are bypassed. However
0.08210 has an identical behavior, thus sod it

lib/DBIx/Class/ResultSet.pm
t/search/preserve_original_rs.t

index 3aa5d23..4e4103a 100644 (file)
@@ -1299,21 +1299,24 @@ sub _construct_results {
     $attrs->{_order_is_artificial} = 1;
   }
 
-  my $cursor = $self->cursor;
-
   # this will be used as both initial raw-row collector AND as a RV of
   # _construct_results. Not regrowing the array twice matters a lot...
   # a surprising amount actually
   my $rows = delete $self->{_stashed_rows};
 
+  my $cursor; # we may not need one at all
+
   my $did_fetch_all = $fetch_all;
 
   if ($fetch_all) {
     # FIXME SUBOPTIMAL - we can do better, cursor->next/all (well diff. methods) should return a ref
-    $rows = [ ($rows ? @$rows : ()), $cursor->all ];
+    $rows = [ ($rows ? @$rows : ()), $self->cursor->all ];
   }
   elsif( $attrs->{collapse} ) {
 
+    # a cursor will need to be closed over in case of collapse
+    $cursor = $self->cursor;
+
     $attrs->{_ordered_for_collapse} = (
       (
         $attrs->{order_by}
@@ -1339,6 +1342,7 @@ sub _construct_results {
 
   if (! $did_fetch_all and ! @{$rows||[]} ) {
     # FIXME SUBOPTIMAL - we can do better, cursor->next/all (well diff. methods) should return a ref
+    $cursor ||= $self->cursor;
     if (scalar (my @r = $cursor->next) ) {
       $rows = [ \@r ];
     }
index 15fdb8d..a87fe9a 100644 (file)
@@ -96,6 +96,7 @@ for my $s (qw/a2a artw cd artw_back/) {
   is ($fresh->count({ cdid => 1}), 1 );
   is ($fresh->count_rs({ cdid => 1})->next, 1 );
 
+  ok (! exists $fresh->{cursor}, 'Still no cursor on fresh rs');
   ok (! exists $fresh->{_attrs}{_sqlmaker_select_args}, 'select args did not leak through' );
 }