Fix func_rs() and as_subselect_rs() to start behaving as advertised
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
index cf6e129..a274ee7 100644 (file)
@@ -12,7 +12,8 @@ use Scalar::Util qw( blessed reftype );
 use SQL::Abstract 'is_literal_value';
 use DBIx::Class::_Util qw(
   dbic_internal_try dbic_internal_catch dump_value emit_loud_diag
-  fail_on_internal_wantarray fail_on_internal_call UNRESOLVABLE_CONDITION
+  fail_on_internal_wantarray fail_on_internal_call
+  UNRESOLVABLE_CONDITION DUMMY_ALIASPAIR
 );
 use DBIx::Class::SQLMaker::Util qw( normalize_sqla_condition extract_equality_conditions );
 use DBIx::Class::ResultSource::FromSpec::Util 'find_join_path_to_alias';
@@ -818,6 +819,7 @@ sub find {
 
   for my $key (keys %$call_cond) {
     if (
+      # either a structure or a result-ish object
       length ref($call_cond->{$key})
         and
       ( $rel_list ||= { map { $_ => 1 } $rsrc->relationships } )
@@ -826,21 +828,45 @@ sub find {
       ! is_literal_value( $call_cond->{$key} )
         and
       # implicitly skip has_many's (likely MC), via the delete()
-      ( ref( my $val = delete $call_cond->{$key} ) ne 'ARRAY' )
+      ( ref( my $foreign_val = delete $call_cond->{$key} ) ne 'ARRAY' )
     ) {
 
       # FIXME: it seems wrong that relationship conditions take precedence...?
       $call_cond = {
         %$call_cond,
 
-        %{ $rsrc->_resolve_relationship_condition(
+        %{ $rsrc->resolve_relationship_condition(
+          require_join_free_values => 1,
           rel_name => $key,
-          foreign_values => $val,
-          infer_values_based_on => {},
+          foreign_values => (
+            (! defined blessed $foreign_val) ? $foreign_val : do {
 
-          self_alias => "\xFE", # irrelevant
-          foreign_alias => "\xFF", # irrelevant
-        )->{inferred_values} },
+              my $f_result_class = $rsrc->related_source($key)->result_class;
+
+              unless( $foreign_val->isa($f_result_class) ) {
+
+                $self->throw_exception(
+                  'Objects supplied to find() must inherit from '
+                . "'$DBIx::Class::ResultSource::__expected_result_class_isa'"
+                ) unless $foreign_val->isa(
+                  $DBIx::Class::ResultSource::__expected_result_class_isa
+                );
+
+                carp_unique(
+                  "Objects supplied to find() via '$key' usually should inherit from "
+                . "the related ResultClass ('$f_result_class'), perhaps you've made "
+                . 'a mistake?'
+                );
+              }
+
+              +{ $foreign_val->get_columns };
+            }
+          ),
+
+          # an API where these are optional would be too cumbersome,
+          # instead always pass in some dummy values
+          DUMMY_ALIASPAIR,
+        )->{join_free_values} },
       };
     }
   }
@@ -2505,10 +2531,12 @@ sub populate {
 
           $colinfo->{$rel}{rs} = $rsrc->related_source($rel)->resultset;
 
-          $colinfo->{$rel}{fk_map} = { reverse %{ $rsrc->_resolve_relationship_condition(
+          $colinfo->{$rel}{fk_map} = { reverse %{ $rsrc->resolve_relationship_condition(
             rel_name => $rel,
-            self_alias => "\xFE", # irrelevant
-            foreign_alias => "\xFF", # irrelevant
+
+            # an API where these are optional would be too cumbersome,
+            # instead always pass in some dummy values
+            DUMMY_ALIASPAIR,
           )->{identity_map} || {} } };
 
         }
@@ -3476,9 +3504,24 @@ but because we isolated the group by into a subselect the above works.
 =cut
 
 sub as_subselect_rs {
+
+  # FIXME - remove at some point in the future (2018-ish)
+  wantarray
+    and
+  carp_unique(
+    'Starting with DBIC@0.082900 as_subselect_rs() always returns a ResultSet '
+  . 'instance regardless of calling context. Please force scalar() context to '
+  . 'silence this warning'
+  )
+    and
+  DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_WANTARRAY
+    and
+  my $sog = fail_on_internal_wantarray
+  ;
+
   my $self = shift;
 
-  my $attrs = $self->_resolved_attrs;
+  my $alias = $self->current_source_alias;
 
   my $fresh_rs = (ref $self)->new (
     $self->result_source
@@ -3488,13 +3531,13 @@ sub as_subselect_rs {
   delete $fresh_rs->{cond};
   delete @{$fresh_rs->{attrs}}{qw/where bind/};
 
-  return $fresh_rs->search( {}, {
+  $fresh_rs->search_rs( {}, {
     from => [{
-      $attrs->{alias} => $self->as_query,
-      -alias  => $attrs->{alias},
+      $alias => $self->as_query,
+      -alias  => $alias,
       -rsrc   => $self->result_source,
     }],
-    alias => $attrs->{alias},
+    alias => $alias,
   });
 }