From: Peter Rabbitson Date: Tue, 7 Jul 2015 20:14:42 +0000 (+0200) Subject: Remove last internal use of the legacy _resolve_condition (find) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=cc10d685d277eb9399e15e0b342fd44aaa0d1a7e;p=dbsrgits%2FDBIx-Class.git Remove last internal use of the legacy _resolve_condition (find) Also fixes the overly coarse 'is it a HASH' check added in 49ca473e/096f4212 --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index a0305c8..cf6e129 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -9,6 +9,7 @@ use DBIx::Class::Carp; 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 @@ -777,7 +778,6 @@ sub find { my $self = shift; my $attrs = (@_ > 1 && ref $_[-1] eq 'HASH' ? pop(@_) : {}); - my $rsrc = $self->result_source; my $constraint_name; if (exists $attrs->{key}) { @@ -790,6 +790,8 @@ sub find { # Parse out the condition from input my $call_cond; + my $rsrc = $self->result_source; + if (ref $_[0] eq 'HASH') { $call_cond = { %{$_[0]} }; } @@ -812,25 +814,34 @@ sub find { } # process relationship data if any + my $rel_list; + for my $key (keys %$call_cond) { if ( length ref($call_cond->{$key}) and - my $relinfo = $rsrc->relationship_info($key) + ( $rel_list ||= { map { $_ => 1 } $rsrc->relationships } ) + ->{$key} and - # implicitly skip has_many's (likely MC) + ! 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' ) ) { - 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, - # supplement condition - # relationship conditions take precedence (?) - @{$call_cond}{keys %$rel_cond} = values %$rel_cond; + %{ $rsrc->_resolve_relationship_condition( + rel_name => $key, + foreign_values => $val, + infer_values_based_on => {}, + + self_alias => "\xFE", # irrelevant + foreign_alias => "\xFF", # irrelevant + )->{inferred_values} }, + }; } } diff --git a/t/sqlmaker/bind_transport.t b/t/sqlmaker/bind_transport.t index aacd59c..93b3c16 100644 --- a/t/sqlmaker/bind_transport.t +++ b/t/sqlmaker/bind_transport.t @@ -18,6 +18,17 @@ my ($ROWS, $OFFSET) = ( my $schema = DBICTest->init_schema(); +$schema->is_executed_sql_bind( + sub { $schema->resultset('Artist')->find( Math::BigInt->new(42) ) }, + [ + [ + 'SELECT me.artistid, me.name, me.rank, me.charfield FROM artist me WHERE me.artistid = ?', + [ { dbic_colname => "me.artistid", sqlt_datatype => "integer" } + => Math::BigInt->new(42) ], + ] + ] +); + my $rs = $schema->resultset('CD')->search({ -and => [ 'me.artist' => { '!=', '666' }, 'me.artist' => { '!=', \[ '?', [ _ne => 'bar' ] ] }, diff --git a/xt/extra/diagnostics/find_via_unsupported_rel.t b/xt/extra/diagnostics/find_via_unsupported_rel.t new file mode 100644 index 0000000..10328e2 --- /dev/null +++ b/xt/extra/diagnostics/find_via_unsupported_rel.t @@ -0,0 +1,31 @@ +BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) } + +use strict; +use warnings; + +use Test::More; +use Test::Exception; + +use DBICTest; + +my $schema = DBICTest->init_schema( no_deploy => 1 ); + +my $artist = $schema->resultset('Artist')->new_result({ artistid => 1 }); + +throws_ok { + $schema->resultset('ArtistUndirectedMap')->find({ + mapped_artists => $artist, + }); +} qr/\QUnable to complete value inferrence - relationship 'mapped_artists' on source 'ArtistUndirectedMap' results in expression(s) instead of definitive values: ( id1 = ? OR id2 = ? )/, + 'proper exception on OR relationship inferrence' +; + +throws_ok { + $schema->resultset('Artwork_to_Artist')->find({ + artist_limited_rank_opaque => $artist + }) +} qr/\QRelationship 'artist_limited_rank_opaque' on source 'Artwork_to_Artist' does not resolve to a 'foreign_values'-based reversed-join-free condition fragment/, + 'proper exception on ipaque custom cond' +; + +done_testing;