From: Rob Kinyon Date: Sun, 22 Feb 2009 03:07:14 +0000 (+0000) Subject: Added support for subqueries in the select and +select sections X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0a62f675479175606ba25cc28e0c28fb17425b0d;p=dbsrgits%2FDBIx-Class-Historic.git Added support for subqueries in the select and +select sections --- diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index 678e173..00c28e9 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -316,6 +316,11 @@ The following will B work: artist_id => $inside_rs->get_column('id')->as_query, }); +=head3 Support + +Subqueries are supported in the where clause (first hashref), and in the +from, select, and +select attributes. + =head3 Correlated subqueries my $cdrs = $schema->resultset('CD'); @@ -338,12 +343,6 @@ That creates the following SQL: WHERE artistid = me.artistid ) -=head2 Where subqueries will work - -Currently, subqueries will B work in the where-clause of a search. In -other words, in the first hashref of a search() method. Work is being done -to make them work as part of the second hashref (from, select, +select, etc). - =head2 Predefined searches You can write your own L class by inheriting from it diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index f017252..6679a57 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -171,6 +171,13 @@ sub _recurse_fields { .'( '.$self->_recurse_fields($fields->{$func}).' )'; } } + # Is the second check absolutely necessary? + elsif ( $ref eq 'REF' and ref($$fields) eq 'ARRAY' ) { + return $self->_bind_to_sql( $fields ); + } + else { + Carp::croak($ref . qq{ unexpected in _recurse_fields()}) + } } sub _order_by { @@ -1409,7 +1416,6 @@ sub _select_args { $attrs->{rows} = 2**48 if not defined $attrs->{rows} and defined $attrs->{offset}; push @args, $attrs->{rows}, $attrs->{offset}; } - return @args; } diff --git a/t/search/subquery.t b/t/search/subquery.t index f8a7e79..2abf1a3 100644 --- a/t/search/subquery.t +++ b/t/search/subquery.t @@ -11,7 +11,7 @@ BEGIN { eval "use SQL::Abstract 1.49"; plan $@ ? ( skip_all => "Needs SQLA 1.49+" ) - : ( tests => 6 ); + : ( tests => 7 ); } use lib qw(t/lib); @@ -36,16 +36,31 @@ my $cdrs = $schema->resultset('CD'); ); } -TODO: { - local $TODO = "'+select' doesn't work with as_query yet."; +{ my $rs = $art_rs->search( {}, { - '+select' => [ + 'select' => [ $cdrs->search({}, { rows => 1 })->get_column('id')->as_query, ], - '+as' => [ - 'cdid', + }, + ); + + my $arr = $rs->as_query; + my ($query, @bind) = @{$$arr}; + is_same_sql_bind( + $query, \@bind, + "SELECT (SELECT id FROM cd me LIMIT 1) FROM artist me", + [], + ); +} + +{ + my $rs = $art_rs->search( + {}, + { + '+select' => [ + $cdrs->search({}, { rows => 1 })->get_column('id')->as_query, ], }, ); @@ -54,7 +69,7 @@ TODO: { my ($query, @bind) = @{$$arr}; is_same_sql_bind( $query, \@bind, - "SELECT me.artistid, me.name, me.rank, me.charfield, (SELECT id FROM cds LIMIT 1) AS cdid FROM artist me", + "SELECT me.artistid, me.name, me.rank, me.charfield, (SELECT id FROM cd me LIMIT 1) FROM artist me", [], ); }