From: Peter Rabbitson Date: Sat, 12 Jun 2010 00:16:26 +0000 (+0200) Subject: Fix grouped count over a joined resultset with clashing columns X-Git-Tag: v0.08123~7 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=9f775126bf5575a72f493da091383e8206b9d56b Fix grouped count over a joined resultset with clashing columns --- diff --git a/Changes b/Changes index 6a07924..d03b1e3 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ Revision history for DBIx::Class column names, so we stay within the 30-char limit (RT#58271) - Fix a Storage/$dbh leak introduced by th migration to Try::Tiny (this is *not* a Try::Tiny bug) + - Fix corner case of count with group-by over a 1:1 join column + where the selector ends up with column name clashes * Misc - Test suite default on-disk database now checks for Win32 diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index e84c83d..004368a 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -1274,6 +1274,8 @@ sub _count_subq_rs { # Calculate subquery selector if (my $g = $sub_attrs->{group_by}) { + my $sql_maker = $rsrc->storage->sql_maker; + # necessary as the group_by may refer to aliased functions my $sel_index; for my $sel (@{$attrs->{select}}) { @@ -1282,7 +1284,17 @@ sub _count_subq_rs { } for my $g_part (@$g) { - push @{$sub_attrs->{select}}, $sel_index->{$g_part} || $g_part; + my $colpiece = $sel_index->{$g_part} || $g_part; + + # disqualify join-based group_by's. Arcane but possible query + # also horrible horrible hack to alias a column (not a func.) + # (probably need to introduce SQLA syntax) + if ($colpiece =~ /\./ && $colpiece !~ /^$attrs->{alias}\./) { + my $as = $colpiece; + $as =~ s/\./__/; + $colpiece = \ sprintf ('%s AS %s', map { $sql_maker->_quote ($_) } ($colpiece, $as) ); + } + push @{$sub_attrs->{select}}, $colpiece; } } else { diff --git a/t/71mysql.t b/t/71mysql.t index 755bbf6..8d5a323 100644 --- a/t/71mysql.t +++ b/t/71mysql.t @@ -250,7 +250,11 @@ NULLINSEARCH: { # check for proper grouped counts { - my $ansi_schema = DBICTest::Schema->connect ($dsn, $user, $pass, { on_connect_call => 'set_strict_mode' }); + my $ansi_schema = DBICTest::Schema->connect ($dsn, $user, $pass, { + on_connect_call => 'set_strict_mode', + quote_char => '`', + name_sep => '.' + }); my $rs = $ansi_schema->resultset('CD'); my $years; @@ -263,6 +267,14 @@ NULLINSEARCH: { 'grouped count correct', ); }, 'Grouped count does not throw'); + + lives_ok( sub { + $ansi_schema->resultset('Owners')->search({}, { + join => 'books', group_by => [ 'me.id', 'books.id' ] + })->count(); + }, 'count on grouped columns with the same name does not throw'); + + } ZEROINSEARCH: {