X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBIHacks.pm;h=ba1faa486776270fa0c66da9075e5837a0226ddf;hb=14e26c5f3516e39d9191ca9b2a9d460f8f495654;hp=fd1bde54a096f3bcbdbc6ee0147fa0329b6de840;hpb=4c2b30d6e53cd05e570ad112e87ad6f96355f695;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBIHacks.pm b/lib/DBIx/Class/Storage/DBIHacks.pm index fd1bde5..ba1faa4 100644 --- a/lib/DBIx/Class/Storage/DBIHacks.pm +++ b/lib/DBIx/Class/Storage/DBIHacks.pm @@ -115,16 +115,30 @@ sub _adjust_select_args_for_complex_prefetch { group_by => ['dummy'], %$inner_attrs, }); - # if a multi-type join was needed in the subquery - add a group_by to simulate the - # collapse in the subq + my $inner_aliastypes = + $self->_resolve_aliastypes_from_select_args( $inner_from, $inner_select, $where, $inner_attrs ); + + # if a multi-type non-selecting (only restricting) join was needed in the subquery + # add a group_by to simulate the collapse in the subq if ( ! $inner_attrs->{group_by} and - first { ! $_->[0]{-is_single} } (@{$inner_from}[1 .. $#$inner_from]) + first { + $inner_aliastypes->{restricting}{$_} + and + ! $inner_aliastypes->{selecting}{$_} + } ( keys %{$inner_aliastypes->{multiplying}||{}} ) ) { - $inner_attrs->{group_by} = $self->_group_over_selection ( + my $unprocessed_order_chunks; + ($inner_attrs->{group_by}, $unprocessed_order_chunks) = $self->_group_over_selection ( $inner_from, $inner_select, $inner_attrs->{order_by} ); + + $self->throw_exception ( + 'A required group_by clause could not be constructed automatically due to a complex ' + . 'order_by criteria. Either order_by columns only (no functions) or construct a suitable ' + . 'group_by by hand' + ) if $unprocessed_order_chunks; } # we already optimized $inner_from above @@ -360,17 +374,27 @@ sub _group_over_selection { # add any order_by parts that are not already present in the group_by # we need to be careful not to add any named functions/aggregates # i.e. order_by => [ ... { count => 'foo' } ... ] + my @leftovers; for ($self->_extract_order_criteria($order_by)) { # only consider real columns (for functions the user got to do an explicit group_by) - next if @$_ != 1; + if (@$_ != 1) { + push @leftovers, $_; + next; + } my $chunk = $_->[0]; - my $colinfo = $rs_column_list->{$chunk} or next; + my $colinfo = $rs_column_list->{$chunk} or do { + push @leftovers, $_; + next; + }; $chunk = "$colinfo->{-source_alias}.$chunk" if $chunk !~ /\./; push @group_by, $chunk unless $group_index{$chunk}++; } - return \@group_by; + return wantarray + ? (\@group_by, (@leftovers ? \@leftovers : undef) ) + : \@group_by + ; } sub _resolve_ident_sources {