grouped prefetch fix
[dbsrgits/DBIx-Class.git] / t / prefetch / grouped.t
index 866f910..19fa923 100644 (file)
@@ -10,6 +10,7 @@ use DBIC::SqlMakerTest;
 plan 'no_plan';
 
 my $schema = DBICTest->init_schema();
+my $sdebug = $schema->storage->debug;
 
 my $cd_rs = $schema->resultset('CD')->search (
   { 'tracks.cd' => { '!=', undef } },
@@ -27,7 +28,6 @@ for ($cd_rs->all) {
   my $track_rs = $schema->resultset ('Track')->search (
     { 'me.cd' => { -in => [ $cd_rs->get_column ('cdid')->all ] } },
     {
-      # the select/as is deliberately silly to test both funcs and refs below
       select => [
         'me.cd',
         { count => 'me.trackid' },
@@ -41,30 +41,31 @@ for ($cd_rs->all) {
     },
   );
 
+  # this used to fuck up ->all, do not remove!
+  ok ($track_rs->first, 'There is stuff in the rs');
+
   is($track_rs->count, 5, 'Prefetched count with groupby');
   is($track_rs->all, 5, 'Prefetched objects with groupby');
 
   {
     my $query_cnt = 0;
     $schema->storage->debugcb ( sub { $query_cnt++ } );
+    $schema->storage->debug (1);
 
-    $track_rs->reset;
     while (my $collapsed_track = $track_rs->next) {
-
       my $cdid = $collapsed_track->get_column('cd');
       is($collapsed_track->get_column('track_count'), 3, "Correct count of tracks for CD $cdid" );
       ok($collapsed_track->cd->title, "Prefetched title for CD $cdid" );
     }
 
-    is ($query_cnt, 0, 'No queries on prefetched titles');
+    is ($query_cnt, 1, 'Single query on prefetched titles');
     $schema->storage->debugcb (undef);
+    $schema->storage->debug ($sdebug);
   }
 
   # Test sql by hand, as the sqlite db will simply paper over
   # improper group/select combinations
   #
-  # the exploded IN needs fixing below, coming in another branch
-  #
   is_same_sql_bind (
     $track_rs->count_rs->as_query,
     '(
@@ -73,7 +74,7 @@ for ($cd_rs->all) {
           SELECT me.cd
             FROM track me
             JOIN cd cd ON cd.cdid = me.cd
-          WHERE ( me.cd IN ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) )
+          WHERE ( me.cd IN ( ?, ?, ?, ?, ? ) )
           GROUP BY me.cd
         )
       count_subq
@@ -89,13 +90,14 @@ for ($cd_rs->all) {
         FROM (
           SELECT me.cd, COUNT (me.trackid) AS track_count,
             FROM track me
-          WHERE ( cd IN ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) )
+            JOIN cd cd ON cd.cdid = me.cd
+          WHERE ( me.cd IN ( ?, ?, ?, ?, ? ) )
           GROUP BY me.cd
           ) as me
         JOIN cd cd ON cd.cdid = me.cd
-      WHERE ( me.cd IN ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) )
+      WHERE ( me.cd IN ( ?, ?, ?, ?, ? ) )
     )',
-    [ map { [ 'me.cd' => $_] } ($cd_rs->get_column ('cdid')->all) ],
+    [ map { [ 'me.cd' => $_] } ( ($cd_rs->get_column ('cdid')->all) x 2 ) ],
     'next() query generated expected SQL',
   );
 
@@ -126,14 +128,19 @@ for ($cd_rs->all) {
 # test a has_many/might_have prefetch at the same level
 # Note that one of the CDs now has 4 tracks instead of 3
 {
-  my $most_tracks_rs = $cd_rs->search ({}, {
-    prefetch => 'liner_notes',  # tracks are alredy prefetched
-    select => ['me.cdid', { count => 'tracks.trackid' } ],
-    as => [qw/cdid track_count/],
-    group_by => 'me.cdid',
-    order_by => { -desc => 'track_count' },
-    rows => 2,
-  });
+  my $most_tracks_rs = $schema->resultset ('CD')->search (
+    {
+      'me.cdid' => { '!=' => undef },  # duh - this is just to test WHERE
+    },
+    {
+      prefetch => [qw/tracks liner_notes/],
+      select => ['me.cdid', { count => 'tracks.trackid' } ],
+      as => [qw/cdid track_count/],
+      group_by => 'me.cdid',
+      order_by => { -desc => 'track_count' },
+      rows => 2,
+    }
+  );
 
   is_same_sql_bind (
     $most_tracks_rs->count_rs->as_query,
@@ -144,7 +151,7 @@ for ($cd_rs->all) {
             FROM cd me
             LEFT JOIN track tracks ON tracks.cd = me.cdid
             LEFT JOIN liner_notes liner_notes ON liner_notes.liner_id = me.cdid
-          WHERE ( tracks.cd IS NOT NULL )
+          WHERE ( me.cdid IS NOT NULL )
           GROUP BY me.cdid
           LIMIT 2
         ) count_subq
@@ -156,20 +163,20 @@ for ($cd_rs->all) {
   is_same_sql_bind (
     $most_tracks_rs->as_query,
     '(
-      SELECT me.cdid, track_count, tracks.trackid, tracks.cd, tracks.position, tracks.title, tracks.last_updated_on, tracks.last_updated_at, liner_notes.liner_id, liner_notes.notes
+      SELECT me.cdid, me.track_count, tracks.trackid, tracks.cd, tracks.position, tracks.title, tracks.last_updated_on, tracks.last_updated_at, liner_notes.liner_id, liner_notes.notes
         FROM (
           SELECT me.cdid, COUNT( tracks.trackid ) AS track_count
             FROM cd me
             LEFT JOIN track tracks ON tracks.cd = me.cdid
-          WHERE ( tracks.cd IS NOT NULL )
+          WHERE ( me.cdid IS NOT NULL )
           GROUP BY me.cdid
-          ORDER BY track_count DESC,
+          ORDER BY track_count DESC
           LIMIT 2
         ) me
         LEFT JOIN track tracks ON tracks.cd = me.cdid
         LEFT JOIN liner_notes liner_notes ON liner_notes.liner_id = me.cdid
-      WHERE ( tracks.cd IS NOT NULL )
-      ORDER BY COUNT track_count DESC, tracks.cd
+      WHERE ( me.cdid IS NOT NULL )
+      ORDER BY track_count DESC, tracks.cd
     )',
     [],
     'next() query generated expected SQL',
@@ -177,10 +184,11 @@ for ($cd_rs->all) {
 
   is ($most_tracks_rs->count, 2, 'Limit works');
   my $top_cd = $most_tracks_rs->first;
-  is ($top_cd->id, 2, 'Correct cd fetched on top'); # 2 because of the slice(1,1) above
+  is ($top_cd->id, 2, 'Correct cd fetched on top'); # 2 because of the slice(1,1) earlier
 
   my $query_cnt = 0;
   $schema->storage->debugcb ( sub { $query_cnt++ } );
+  $schema->storage->debug (1);
 
   is ($top_cd->get_column ('track_count'), 4, 'Track count fetched correctly');
   is ($top_cd->tracks->count, 4, 'Count of prefetched tracks rs still correct');
@@ -193,4 +201,5 @@ for ($cd_rs->all) {
 
   is ($query_cnt, 0, 'No queries executed during prefetched data access');
   $schema->storage->debugcb (undef);
+  $schema->storage->debug ($sdebug);
 }