Skip Menu |

This queue is for tickets about the SQL-Statement CPAN distribution.

Report information
The Basics
Id: 42263
Status: resolved
Priority: 0/
Queue: SQL-Statement

People
Owner: REHSACK [...] cpan.org
Requestors: bitcard [...] haeleth.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in:
  • 1.12
  • 1.13
  • 1.14
  • 1.15
  • 1.16_01
  • 1.16_02
  • 1.16_03
  • 1.16_04
Fixed in: (no value)



Subject: GROUP BY doesn't group on multiple columns
The GROUP BY implementation is incomplete: while multiple columns are accepted, SQL::Statement silently ignores all but the last named column. In other words, GROUP BY foo, bar, baz is treated exactly the same as GROUP BY baz There's a test in the test suite that claims to be for 'GROUP BY several columns', but unfortunately the test data has the property that including or excluding the first column does not affect the grouping ... so the test fails to fail. :) I attach a little patch that fixes the test by providing a better set of data. Separately, I also attach a quick-and-dirty patch for the bug itself. I've been using this myself for a couple of years, but you probably won't want to apply it "as is"; it uses join() to create hash keys, with all the problems that implies.
Subject: implement-multicolumn-group-by.patch
diff -aur SQL-Statement-1.16_04/lib/SQL/Statement.pm SQL-Statement-1.16_04-patched/lib/SQL/Statement.pm --- SQL-Statement-1.16_04/lib/SQL/Statement.pm 2009-01-04 23:01:16.000000000 +0000 +++ SQL-Statement-1.16_04-patched/lib/SQL/Statement.pm 2009-01-09 23:16:34.000000000 +0000 @@ -1445,7 +1445,7 @@ { push @$set_cols, $_->{name}; } - my ( $keycol, $keynum ); + my @keycols = (); for my $i ( 0 .. $numcols - 1 ) { my $arg = $self->{"set_function"}->[$i]->{"arg"}; @@ -1456,8 +1456,7 @@ $arg = $set_cols->[$i]; # $arg =$columns_requested[$i]; - $keycol = $self->{"set_function"}->[$i]->{"name"}; - $keynum = $colnum{ uc $arg }; + push @keycols, $colnum{ uc $arg }; } $self->{"set_function"}->[$i]->{"sel_col_num"} = $colnum{ uc $arg }; } @@ -1471,7 +1470,7 @@ # $keynum=$i if uc $display_cols->[$i]->{name} eq uc $keyfield; #printf "%s.%s,%s\n",$i,$display_cols->[$i]->{name},$keyfield; # } - my $g = SQL::Statement::Group->new( $keynum, $display_cols, $rows ); + my $g = SQL::Statement::Group->new( \@keycols, $display_cols, $rows ); $rows = $g->calc; my $x = [ map { $_->{name} } @$display_cols ]; $self->{NAME} = [ map { $_->{name} } @$display_cols ]; @@ -2552,9 +2551,9 @@ sub new { my $class = shift; - my ( $keycol, $display_cols, $ary ) = @_; + my ( $keycols, $display_cols, $ary ) = @_; my $self = { - keycol => $keycol, + keycols => $keycols, display_cols => $display_cols, records => $ary, }; @@ -2634,15 +2633,16 @@ sub ary2hash { - my $self = shift; - my $ary = shift; - my $keycolnum = $self->{keycol} || 0; + my $self = shift; + my $ary = shift; + my @keycolnums = @{ $self->{keycols} || [0] }; my $hash; my @keys; my %is_key; for my $row (@$ary) { - my $key = $row->[$keycolnum]; + # This may fail if data contains \x01. + my $key = join "\x01", map { $row->[$_] } @keycolnums; #die "@$row" unless defined $key; push @{ $hash->{$key} }, $row;
Subject: fix-broken-test.patch
diff -aur SQL-Statement-1.16_04/t/06group.t SQL-Statement-1.16_04-patched/t/06group.t --- SQL-Statement-1.16_04/t/06group.t 2009-01-04 19:52:14.000000000 +0000 +++ SQL-Statement-1.16_04-patched/t/06group.t 2009-01-09 22:39:13.000000000 +0000 @@ -21,14 +21,14 @@ ok('2700~1000^' eq query2str($sth),'AGGREGATE FUNCTIONS WITHOUT GROUP BY'); $sth=$dbh->prepare(" - SELECT region,SUM(sales), MAX(sales) FROM biz GROUP BY region + SELECT class,SUM(sales), MAX(sales) FROM biz GROUP BY class "); -ok('West~2000~1000^East~700~700^' eq query2str($sth),'GROUP BY one column'); +ok('Car~2000~1000^Truck~700~400^' eq query2str($sth),'GROUP BY one column'); $sth=$dbh->prepare(" - SELECT region,store,SUM(sales), MAX(sales) FROM biz GROUP BY region,store + SELECT color,class,SUM(sales), MAX(sales) FROM biz GROUP BY color,class "); -ok('West~Los Angeles~1500~1000^West~San Diego~500~500^East~Boston~700~700^' +ok('White~Car~1000~1000^Blue~Car~500~500^White~Truck~700~400^Red~Car~500~500^' eq query2str($sth),'GROUP BY several columns'); sub query2str { @@ -44,8 +44,9 @@ return $str; } __END__ -CREATE TEMP TABLE biz (region TEXT, store TEXT, sales INTEGER) -INSERT INTO biz VALUES ('West','Los Angeles',1000 ) -INSERT INTO biz VALUES ('West','San Diego' ,500 ) -INSERT INTO biz VALUES ('West','Los Angeles',500 ) -INSERT INTO biz VALUES ('East','Boston' ,700 ) +CREATE TEMP TABLE biz (class TEXT, color TEXT, sales INTEGER) +INSERT INTO biz VALUES ('Car' ,'White',1000) +INSERT INTO biz VALUES ('Car' ,'Blue' ,500 ) +INSERT INTO biz VALUES ('Truck','White',400 ) +INSERT INTO biz VALUES ('Car' ,'Red' ,500 ) +INSERT INTO biz VALUES ('Truck','White',300 )
Patch verified and applied. If the problem still persists, reopen the tasks please.