use DBIx::Class::ResultSetColumn;
use DBIx::Class::ResultClass::HashRefInflator;
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';
my $self = shift;
my $attrs = (@_ > 1 && ref $_[-1] eq 'HASH' ? pop(@_) : {});
- my $rsrc = $self->result_source;
my $constraint_name;
if (exists $attrs->{key}) {
# Parse out the condition from input
my $call_cond;
+ my $rsrc = $self->result_source;
+
if (ref $_[0] eq 'HASH') {
$call_cond = { %{$_[0]} };
}
}
# process relationship data if any
+ my $rel_list;
+
for my $key (keys %$call_cond) {
if (
+ # either a structure or a result-ish object
length ref($call_cond->{$key})
and
- my $relinfo = $rsrc->relationship_info($key)
+ ( $rel_list ||= { map { $_ => 1 } $rsrc->relationships } )
+ ->{$key}
+ and
+ ! is_literal_value( $call_cond->{$key} )
and
- # implicitly skip has_many's (likely MC)
- ( ref( my $val = delete $call_cond->{$key} ) ne 'ARRAY' )
+ # implicitly skip has_many's (likely MC), via the delete()
+ ( ref( my $foreign_val = delete $call_cond->{$key} ) ne 'ARRAY' )
) {
- my ($rel_cond, $crosstable) = $rsrc->_resolve_condition(
- $relinfo->{cond}, $val, $key, $key
- );
- $self->throw_exception("Complex condition via relationship '$key' is unsupported in find()")
- if $crosstable or ref($rel_cond) ne 'HASH';
+ # FIXME: it seems wrong that relationship conditions take precedence...?
+ $call_cond = {
+ %$call_cond,
+
+ %{ $rsrc->_resolve_relationship_condition(
+ require_join_free_values => 1,
+ rel_name => $key,
+ foreign_values => (
+ (! defined blessed $foreign_val) ? $foreign_val : do {
+
+ my $f_result_class = $rsrc->related_source($key)->result_class;
+
+ unless( $foreign_val->isa($f_result_class) ) {
- # supplement condition
- # relationship conditions take precedence (?)
- @{$call_cond}{keys %$rel_cond} = values %$rel_cond;
+ $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} },
+ };
}
}
$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} || {} } };
}