From: Peter Rabbitson Date: Sat, 23 Feb 2013 15:44:13 +0000 (+0100) Subject: Properly wrap a subquery around grouped resultsets in case of $rscol->func($func) X-Git-Tag: v0.08242~1 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=3214abc7114c66f6c342ef3c8180ae0fc5d68a8d;p=dbsrgits%2FDBIx-Class.git Properly wrap a subquery around grouped resultsets in case of $rscol->func($func) --- diff --git a/Changes b/Changes index 436771f..ae17bab 100644 --- a/Changes +++ b/Changes @@ -19,6 +19,8 @@ Revision history for DBIx::Class - Properly consider unselected order_by criteria during complex subqueried prefetch - Properly support "MySQL-style" left-side group_by with prefetch + - Fix $grouped_rs->get_column($col)->func($func) producing incorrect + SQL (RT#81127) 0.08209 2013-03-01 12:56 (UTC) * New Features / Changes diff --git a/lib/DBIx/Class/ResultSetColumn.pm b/lib/DBIx/Class/ResultSetColumn.pm index 5f37d89..3705d50 100644 --- a/lib/DBIx/Class/ResultSetColumn.pm +++ b/lib/DBIx/Class/ResultSetColumn.pm @@ -422,12 +422,19 @@ Creates the resultset that C uses to run its query. sub func_rs { my ($self,$function) = @_; - return $self->{_parent_resultset}->search( - undef, { - select => {$function => $self->{_select}}, - as => [$self->{_as}], - }, - ); + + my $rs = $self->{_parent_resultset}; + my $select = $self->{_select}; + + # wrap a grouped rs + if ($rs->_resolved_attrs->{group_by}) { + $select = $self->{_as}; + $rs = $rs->as_subselect_rs; + } + + $rs->search( undef, { + columns => { $self->{_as} => { $function => $select } } + } ); } =head2 throw_exception diff --git a/t/88result_set_column.t b/t/88result_set_column.t index 69eb911..ff8db9e 100644 --- a/t/88result_set_column.t +++ b/t/88result_set_column.t @@ -167,4 +167,29 @@ is_same_sql_bind ( 'Correct SQL for prefetch/order_by/group_by' ); +# test aggregate on a function +{ + my $tr_rs = $schema->resultset("Track"); + $tr_rs->create({ cd => 2, title => 'dealbreaker' }); + + is( + $tr_rs->get_column('cd')->max, + 5, + "Correct: Max cd in Track is 5" + ); + + my $track_counts_per_cd_via_group_by = $tr_rs->search({}, { + columns => [ 'cd', { cnt => { count => 'trackid', -as => 'cnt' } } ], + group_by => 'cd', + })->get_column('cnt'); + + is ($track_counts_per_cd_via_group_by->max, 4, 'Correct max tracks per cd'); + is ($track_counts_per_cd_via_group_by->min, 3, 'Correct min tracks per cd'); + is ( + sprintf('%0.1f', $track_counts_per_cd_via_group_by->func('avg') ), + '3.2', + 'Correct avg tracks per cd' + ); +} + done_testing;