Added support for subqueries in the select and +select sections
Rob Kinyon [Sun, 22 Feb 2009 03:07:14 +0000 (03:07 +0000)]
lib/DBIx/Class/Manual/Cookbook.pod
lib/DBIx/Class/Storage/DBI.pm
t/search/subquery.t

index 678e173..00c28e9 100644 (file)
@@ -316,6 +316,11 @@ The following will B<not> 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<only> 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<DBIx::Class::ResultSet> class by inheriting from it
index f017252..6679a57 100644 (file)
@@ -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;
 }
 
index f8a7e79..2abf1a3 100644 (file)
@@ -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",
     [],
   );
 }