Fix count of group_by over aliased function
Peter Rabbitson [Thu, 18 Feb 2010 23:35:01 +0000 (23:35 +0000)]
Changes
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/Storage/DBI.pm
t/count/group_by_func.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index 627afda..c46b6ad 100644 (file)
--- 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
index 1b12895..4e399a3 100644 (file)
@@ -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
index c1f852b..61f7572 100644 (file)
@@ -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 (file)
index 0000000..661cc9e
--- /dev/null
@@ -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;