From: Peter Rabbitson Date: Sat, 21 Apr 2012 04:03:34 +0000 (+0200) Subject: Do not artificially order the internals of a has_many prefetch subquery X-Git-Tag: v0.08197~22 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=946f626022c63fd269d9d985c2abeabb52871027 Do not artificially order the internals of a has_many prefetch subquery 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 --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 88409b0..2f76830 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -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 diff --git a/lib/DBIx/Class/Storage/DBIHacks.pm b/lib/DBIx/Class/Storage/DBIHacks.pm index 3efd488..cb75f14 100644 --- a/lib/DBIx/Class/Storage/DBIHacks.pm +++ b/lib/DBIx/Class/Storage/DBIHacks.pm @@ -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 diff --git a/t/prefetch/grouped.t b/t/prefetch/grouped.t index c50b7ef..760e381 100644 --- a/t/prefetch/grouped.t +++ b/t/prefetch/grouped.t @@ -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 diff --git a/t/prefetch/with_limit.t b/t/prefetch/with_limit.t index 522324c..1d2aa84 100644 --- a/t/prefetch/with_limit.t +++ b/t/prefetch/with_limit.t @@ -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