Do not artificially order the internals of a has_many prefetch subquery
Peter Rabbitson [Sat, 21 Apr 2012 04:03:34 +0000 (06:03 +0200)]
Thre is no point using the artificial order which is only needed for efficient
collapse. The user didn't request an order - this means any rows will do

lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/Storage/DBIHacks.pm
t/prefetch/grouped.t
t/prefetch/with_limit.t

index 88409b0..2f76830 100644 (file)
@@ -3487,6 +3487,7 @@ sub _resolved_attrs {
     # default order for collapsing unless the user asked for something
     $attrs->{order_by} = [ map { "$alias.$_" } $source->primary_columns ];
     $attrs->{_ordered_for_collapse} = 1;
+    $attrs->{_order_is_artificial} = 1;
   }
 
   # if both page and offset are specified, produce a combined offset
index 3efd488..cb75f14 100644 (file)
@@ -72,7 +72,6 @@ sub _adjust_select_args_for_complex_prefetch {
   $self->throw_exception ('Complex prefetches are not supported on resultsets with a custom from attribute')
     if (ref $from ne 'ARRAY' || ref $from->[0] ne 'HASH' || ref $from->[1] ne 'ARRAY');
 
-
   # generate inner/outer attribute lists, remove stuff that doesn't apply
   my $outer_attrs = { %$attrs };
   delete $outer_attrs->{$_} for qw/where bind rows offset group_by having/;
@@ -80,6 +79,9 @@ sub _adjust_select_args_for_complex_prefetch {
   my $inner_attrs = { %$attrs, _is_internal_subuery => 1 };
   delete $inner_attrs->{$_} for qw/for collapse _prefetch_selector_range select as/;
 
+  # if the user did not request it, there is no point using it inside
+  delete $inner_attrs->{order_by} if delete $inner_attrs->{_order_is_artificial};
+
   # generate the inner/outer select lists
   # for inside we consider only stuff *not* brought in by the prefetch
   # on the outside we substitute any function for its alias
index c50b7ef..760e381 100644 (file)
@@ -294,7 +294,6 @@ for ($cd_rs->all) {
               FROM cd me
               JOIN artist artist ON artist.artistid = me.artist
             GROUP BY me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
-            ORDER BY me.cdid
           ) me
           JOIN artist artist ON artist.artistid = me.artist
           ORDER BY me.cdid
@@ -323,7 +322,6 @@ for ($cd_rs->all) {
               JOIN artist artist ON artist.artistid = me.artist
             WHERE ( tracks.title != ? )
             GROUP BY me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
-            ORDER BY me.cdid
           ) me
           LEFT JOIN track tracks ON tracks.cd = me.cdid
           JOIN artist artist ON artist.artistid = me.artist
index 522324c..1d2aa84 100644 (file)
@@ -183,7 +183,6 @@ is_same_sql_bind (
           FROM cd me
           JOIN artist artist ON artist.artistid = me.artist
         WHERE ( ( artist.name = ? AND me.year = ? ) )
-        ORDER BY me.cdid
         LIMIT ?
       ) me
       LEFT JOIN track tracks