Populate caches for related result sets even if they're empty
Dagfinn Ilmari Mannsåker [Fri, 28 Mar 2014 16:48:17 +0000 (16:48 +0000)]
lib/DBIx/Class/ResultSet.pm
t/prefetch/empty_cache.t [new file with mode: 0644]

index ffade21..84a2b13 100644 (file)
@@ -3186,11 +3186,11 @@ sub related_resultset {
 
     if (my $cache = $self->get_cache) {
       my @related_cache = map
-        { @{$_->related_resultset($rel)->get_cache||[]} }
+        { $_->related_resultset($rel)->get_cache || () }
         @$cache
       ;
 
-      $new->set_cache(\@related_cache) if @related_cache;
+      $new->set_cache([ map @$_, @related_cache ]) if @related_cache == @$cache;
     }
 
     $new;
diff --git a/t/prefetch/empty_cache.t b/t/prefetch/empty_cache.t
new file mode 100644 (file)
index 0000000..9f42d5a
--- /dev/null
@@ -0,0 +1,39 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+my $queries;
+my $debugcb = sub { $queries++; };
+my $orig_debug = $schema->storage->debug;
+
+{
+  $queries = 0;
+  $schema->storage->debugcb($debugcb);
+  $schema->storage->debug(1);
+
+  my $cds_rs = $schema->resultset('CD')
+    ->search(\'0 = 1', { prefetch => 'tracks', cache => 1 });
+
+  my @cds = $cds_rs->all;
+  is( $queries, 1, '->all on empty original resultset hit db' );
+  is_deeply( $cds_rs->get_cache, [], 'empty cache on original resultset' );
+  is( 0+@cds, 0, 'empty original resultset' );
+
+  my $tracks_rs = $cds_rs->related_resultset('tracks');
+  is_deeply( $tracks_rs->get_cache, [], 'empty cache on related resultset' );
+
+  my @tracks = $tracks_rs->all;
+  is( $queries, 1, "->all on empty related resultset didn't hit db" );
+  is( 0+@tracks, 0, 'empty related resultset' );
+
+  $schema->storage->debugcb(undef);
+  $schema->storage->debug($orig_debug);
+}
+
+done_testing;