This is made out of awesome
Peter Rabbitson [Sun, 17 Jan 2010 15:29:20 +0000 (15:29 +0000)]
lib/DBIx/Class/Storage/DBIHacks.pm
t/count/prefetch.t
t/prefetch/grouped.t
t/search/related_strip_prefetch.t

index 43faccf..2d9fd35 100644 (file)
@@ -17,24 +17,30 @@ use Carp::Clan qw/^DBIx::Class/;
 
 #
 # This code will remove non-selecting/non-restricting joins from
-# {from} specs, aiding the RDBMS query optimizer.
+# {from} specs, aiding the RDBMS query optimizer
 #
 sub _prune_unused_joins {
-  my $self = shift;
+  my ($self) = shift;
+
+  my ($from, $select, $where, $attrs) = @_;
 
-  my $from = shift;
   if (ref $from ne 'ARRAY' || ref $from->[0] ne 'HASH' || ref $from->[1] ne 'ARRAY') {
     return $from;   # only standard {from} specs are supported
   }
 
-  my $aliastypes = $self->_resolve_aliastypes_from_select_args($from, @_);
+  my $aliastypes = $self->_resolve_aliastypes_from_select_args(@_);
+
+  # a grouped set will not be affected by amount of rows. Thus any
+  # {multiplying} joins can go
+  delete $aliastypes->{multiplying} if $attrs->{group_by};
+
 
   my @newfrom = $from->[0]; # FROM head is always present
 
   my %need_joins = (map { %{$_||{}} } (values %$aliastypes) );
   for my $j (@{$from}[1..$#$from]) {
     push @newfrom, $j if (
-      ! $j->[0]{-alias} # legacy crap
+      (! $j->[0]{-alias}) # legacy crap
         ||
       $need_joins{$j->[0]{-alias}}
     );
index 654520b..7bc4708 100644 (file)
@@ -55,12 +55,13 @@ my $schema = DBICTest->init_schema();
           SELECT genre.genreid
             FROM (
               SELECT me.artistid, me.name, me.rank, me.charfield
-                FROM artist me GROUP BY 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
+          WHERE ( genre.name = ? )
+          GROUP BY genre.genreid
         )
       count_subq
     )',
index 5d0905e..ca4209d 100644 (file)
@@ -148,7 +148,6 @@ for ($cd_rs->all) {
         FROM (
           SELECT me.cdid
             FROM cd me
-            LEFT JOIN track tracks ON tracks.cd = me.cdid
           WHERE ( me.cdid IS NOT NULL )
           GROUP BY me.cdid
           LIMIT 2
index c65e696..419fd32 100644 (file)
@@ -25,12 +25,11 @@ is_same_sql_bind (
         SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
           FROM cd me
           JOIN artist artist ON artist.artistid = me.artist
-          LEFT JOIN track tracks ON tracks.cd = me.cdid
+          LEFT JOIN track tracks ON tracks.cd = me.cdid 
         WHERE ( tracks.id != ? )
         LIMIT 2
       ) me
       JOIN artist artist ON artist.artistid = me.artist
-      LEFT JOIN track tracks ON tracks.cd = me.cdid
       JOIN tags tags ON tags.cd = me.cdid
     WHERE ( tags.tag IS NOT NULL )
     GROUP BY tags.tagid, tags.cd, tags.tag