First half of distinct cleanup
Peter Rabbitson [Thu, 10 Dec 2009 08:53:38 +0000 (08:53 +0000)]
Changes
lib/DBIx/Class/ResultSet.pm
t/count/prefetch.t
t/prefetch/via_search_related.t

diff --git a/Changes b/Changes
index 674e984..213bc91 100644 (file)
--- a/Changes
+++ b/Changes
@@ -5,6 +5,7 @@ Revision history for DBIx::Class
           in order_by also need to be aded to the resulting group_by)
         - Do not attempt to deploy FK constraints pointing to a View
         - Fix count/objects from search_related on limited resultset
+        - Stop propagating distinct => 1 over search_related chains
         - Make sure populate() inherits the resultset conditions just
           like create() does
         - Make get_inflated_columns behave identically to get_columns
index e33411d..6af5f63 100644 (file)
@@ -2626,7 +2626,7 @@ sub _chain_relationship {
   # ->_resolve_join as otherwise they get lost - captainL
   my $join = $self->_merge_attr( $attrs->{join}, $attrs->{prefetch} );
 
-  delete @{$attrs}{qw/join prefetch collapse select as columns +select +as +columns/};
+  delete @{$attrs}{qw/join prefetch collapse distinct select as columns +select +as +columns/};
 
   my $seen = { %{ (delete $attrs->{seen_join}) || {} } };
 
index 6959400..ad4b23c 100644 (file)
@@ -54,19 +54,15 @@ my $schema = DBICTest->init_schema();
         FROM (
           SELECT genre.genreid
             FROM (
-              SELECT cds.cdid, cds.artist, cds.title, cds.year, cds.genreid, cds.single_track
-                FROM (
-                  SELECT me.artistid, me.name, me.rank, me.charfield
-                    FROM artist me GROUP BY me.artistid, me.name, me.rank, me.charfield
-                ) me
-                LEFT JOIN cd cds ON cds.artist = me.artistid
-              GROUP BY cds.cdid, cds.artist, cds.title, cds.year, cds.genreid, cds.single_track
-            ) cds
+              SELECT me.artistid, me.name, me.rank, me.charfield
+                FROM artist me GROUP BY me.artistid, me.name, me.rank, me.charfield
+            ) me
+            JOIN cd cds ON cds.artist = me.artistid
             JOIN genre genre ON genre.genreid = cds.genreid
             LEFT JOIN cd cds_2 ON cds_2.genreid = genre.genreid
-          WHERE ( genre.name = ? )
-          GROUP BY genre.genreid
-        ) count_subq
+          WHERE ( genre.name = ? ) GROUP BY genre.genreid
+        )
+      count_subq
     )',
     [ [ 'genre.name' => 'emo' ] ],
   );
index a9f3f8a..fbaeeef 100644 (file)
@@ -109,26 +109,30 @@ lives_ok (sub {
     is($rs->search_related('cds')->count, 4, 'prefetch without distinct (count)');
 
 
-    $rs = $artist_rs->search(undef, {distinct => 1})
-                ->search_related('cds')->search_related('genre',
+    $rs = $artist_rs->search_related('cds', {}, { distinct => 1})->search_related('genre',
                     { 'genre.name' => 'vague genre' },
                  );
+    is($rs->all, 2, 'distinct does not propagate over search_related (objects)');
+    is($rs->count, 2, 'distinct does not propagate over search_related (count)');
+
+    $rs = $rs->search ({}, { distinct => 1} );
     is($rs->all, 1, 'distinct without prefetch (objects)');
     is($rs->count, 1, 'distinct without prefetch (count)');
 
 
-    $rs = $artist_rs->search({}, {distinct => 1})
-                ->search_related('cds')->search_related('genre',
+    $rs = $artist_rs->search_related('cds')->search_related('genre',
                     { 'genre.name' => 'vague genre' },
-                    { prefetch => 'cds' },
+                    { prefetch => 'cds', distinct => 1 },
                  );
     is($rs->all, 1, 'distinct with prefetch (objects)');
     is($rs->count, 1, 'distinct with prefetch (count)');
+
+  TODO: {
+    local $TODO = "This makes another 2 trips to the database, it can't be right";
     # artist -> 2 cds -> 2 genres -> 2 cds for each genre + distinct = 2
     is($rs->search_related('cds')->all, 2, 'prefetched distinct with prefetch (objects)');
     is($rs->search_related('cds')->count, 2, 'prefetched distinct with prefetch (count)');
-
-
+  }
 
 }, 'distinct generally works with prefetch on deep search_related chains');