From: Peter Rabbitson Date: Thu, 18 Feb 2010 23:35:01 +0000 (+0000) Subject: Fix count of group_by over aliased function X-Git-Tag: v0.08120~28 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=4fff7913ca44081e9c3d901912fdfba5e125d3c7 Fix count of group_by over aliased function --- diff --git a/Changes b/Changes index 627afda..c46b6ad 100644 --- a/Changes +++ b/Changes @@ -1,7 +1,8 @@ Revision history for DBIx::Class - Make sure possibly overwritten deployment_statements methods in - schemas get called on $schema->deploy. + schemas get called on $schema->deploy + - Fix count() with group_by aliased-function resultsets 0.08119 2010-02-15 09:36:00 (UTC) - Add $rs->is_ordered to test for existing order_by on a resultset diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 1b12895..4e399a3 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -1264,7 +1264,7 @@ sub _count_subq_rs { $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } ($rsrc->primary_columns) ] } - $sub_attrs->{select} = $rsrc->storage->_subq_count_select ($rsrc, $sub_attrs); + $sub_attrs->{select} = $rsrc->storage->_subq_count_select ($rsrc, $attrs); # this is so that the query can be simplified e.g. # * ordering can be thrown away in things like Top limit diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index c1f852b..61f7572 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -1896,7 +1896,33 @@ sub _count_select { # sub _subq_count_select { my ($self, $source, $rs_attrs) = @_; - return $rs_attrs->{group_by} if $rs_attrs->{group_by}; + + if (my $groupby = $rs_attrs->{group_by}) { + + my $avail_columns = $self->_resolve_column_info ($rs_attrs->{from}); + + my $sel_index; + for my $sel (@{$rs_attrs->{select}}) { + if (ref $sel eq 'HASH' and $sel->{-as}) { + $sel_index->{$sel->{-as}} = $sel; + } + } + + my @selection; + for my $g_part (@$groupby) { + if (ref $g_part or $avail_columns->{$g_part}) { + push @selection, $g_part; + } + elsif ($sel_index->{$g_part}) { + push @selection, $sel_index->{$g_part}; + } + else { + $self->throw_exception ("group_by criteria '$g_part' not contained within current resultset source(s)"); + } + } + + return \@selection; + } my @pcols = map { join '.', $rs_attrs->{alias}, $_ } ($source->primary_columns); return @pcols ? \@pcols : [ 1 ]; diff --git a/t/count/group_by_func.t b/t/count/group_by_func.t new file mode 100644 index 0000000..661cc9e --- /dev/null +++ b/t/count/group_by_func.t @@ -0,0 +1,36 @@ +use strict; +use warnings; + +use Test::More; + +use lib qw(t/lib); + +use DBICTest; + +my $schema = DBICTest->init_schema(); + +my $rs = $schema->resultset ('CD')->search ({}, { + select => [ + { substr => [ 'title', 1, 1 ], -as => 'initial' }, + { count => '*' }, + ], + as => [qw/title_initial cnt/], + group_by => ['initial'], + order_by => { -desc => 'initial' }, + result_class => 'DBIx::Class::ResultClass::HashRefInflator', +}); + +is_deeply ( + [$rs->all], + [ + { title_initial => 'S', cnt => '1' }, + { title_initial => 'G', cnt => '1' }, + { title_initial => 'F', cnt => '1' }, + { title_initial => 'C', cnt => '2' }, + ], + 'Correct result', +); + +is ($rs->count, 4, 'Correct count'); + +done_testing;