X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBIHacks.pm;h=dd536552470e4d5c2a4b93f5ffc97f8184704a2d;hb=d64a273452933a67afa721826249b7a1978d4754;hp=f549204cea514652f1e6ae43fd635ac9417fdd9d;hpb=539ffe8768e85b2061aa3bb3616da4f848a582f3;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBIHacks.pm b/lib/DBIx/Class/Storage/DBIHacks.pm index f549204..dd53655 100644 --- a/lib/DBIx/Class/Storage/DBIHacks.pm +++ b/lib/DBIx/Class/Storage/DBIHacks.pm @@ -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}} ); @@ -43,7 +49,6 @@ sub _prune_unused_joins { return \@newfrom; } - # # This is the code producing joined subqueries like: # SELECT me.*, other.* FROM ( SELECT me.* FROM ... ) JOIN other ON ... @@ -92,6 +97,7 @@ sub _adjust_select_args_for_complex_prefetch { } # construct the inner $from for the subquery + # we need to prune first, because this will determine if we need a group_bu below my $inner_from = $self->_prune_unused_joins ($from, $inner_select, $where, $inner_attrs); # if a multi-type join was needed in the subquery - add a group_by to simulate the @@ -255,7 +261,7 @@ sub _resolve_aliastypes_from_select_args { for my $type (keys %$aliases_by_type) { for my $alias (keys %{$aliases_by_type->{$type}}) { $aliases_by_type->{$type}{$_} = 1 - for (@{ $alias_list->{$alias}{-join_path} || [] }); + for (map { keys %$_ } @{ $alias_list->{$alias}{-join_path} || [] }); } } @@ -400,7 +406,7 @@ sub _straight_join_to_node { # anyway, and deep cloning is just too fucking expensive # So replace the first hashref in the node arrayref manually my @new_from = ($from->[0]); - my $sw_idx = { map { $_ => 1 } @$switch_branch }; + my $sw_idx = { map { values %$_ => 1 } @$switch_branch }; for my $j (@{$from}[1 .. $#$from]) { my $jalias = $j->[0]{-alias};