Skip to content

Commit

Permalink
Tighten up value inferrence in relationship resolution
Browse files Browse the repository at this point in the history
Read under -w
  • Loading branch information
ribasushi committed Sep 26, 2016
1 parent 616ca57 commit d8516e9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
36 changes: 24 additions & 12 deletions lib/DBIx/Class/ResultSource.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2495,12 +2495,12 @@ sub _resolve_relationship_condition {
$ret = $subconds[0];
}
else {
# we are discarding inferred values here... likely incorrect...
# then again - the entire thing is an OR, so we *can't* use them anyway
for my $subcond ( @subconds ) {
$self->throw_exception('Either all or none of the OR-condition members must resolve to a join-free condition')
if ( $ret and ( $ret->{join_free_condition} xor $subcond->{join_free_condition} ) );

# we are discarding inferred_values from individual 'OR' branches here
# see @nonvalues checks below
$subcond->{$_} and push @{$ret->{$_}}, $subcond->{$_} for (qw(condition join_free_condition));
}
}
Expand Down Expand Up @@ -2535,31 +2535,43 @@ sub _resolve_relationship_condition {

my $jfc_eqs = extract_equality_conditions( $jfc, 'consider_nulls' );

if (keys %$jfc_eqs) {

for (keys %$jfc) {
for (keys %$jfc) {
if( $_ =~ /^-/ ) {
push @nonvalues, { $_ => $jfc->{$_} };
}
else {
# $jfc is fully qualified by definition
my ($col) = $_ =~ /\.(.+)/;
my ($col) = $_ =~ /\.(.+)/ or carp_unique(
'Internal error - extract_equality_conditions() returned a '
. "non-fully-qualified key '$_'. *Please* file a bugreport "
. "including your definition of $exception_rel_id"
);

if (exists $jfc_eqs->{$_} and ($jfc_eqs->{$_}||'') ne UNRESOLVABLE_CONDITION) {
$ret->{inferred_values}{$col} = $jfc_eqs->{$_};
}
elsif ( !$args->{infer_values_based_on} or ! exists $args->{infer_values_based_on}{$col} ) {
push @nonvalues, $col;
push @nonvalues, { $_ => $jfc->{$_} };
}
}

# all or nothing
delete $ret->{inferred_values} if @nonvalues;
}

# all or nothing
delete $ret->{inferred_values} if @nonvalues;
}

# did the user explicitly ask
if ($args->{infer_values_based_on}) {

$self->throw_exception(sprintf (
"Unable to complete value inferrence - custom $exception_rel_id returns conditions instead of values for column(s): %s",
map { "'$_'" } @nonvalues
"Unable to complete value inferrence - $exception_rel_id results in expression(s) instead of definitive values: %s",
do {
# FIXME - used for diag only, but still icky
my $sqlm = $self->schema->storage->sql_maker;
local $sqlm->{quote_char};
local $sqlm->{_dequalify_idents} = 1;
($sqlm->_recurse_where({ -and => \@nonvalues }))[0]
}
)) if @nonvalues;


Expand Down
6 changes: 5 additions & 1 deletion t/relationship/core.t
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,11 @@ is($undir_maps->count, 1, 'found 1 undirected map for artist 2');
{
my $artist_to_mangle = $schema->resultset('Artist')->find(2);

$artist_to_mangle->set_from_related( artist_undirected_maps => { id1 => 42 } );
throws_ok {
$artist_to_mangle->set_from_related( artist_undirected_maps => { id1 => 42 } )
} qr/\QUnable to complete value inferrence - relationship 'artist_undirected_maps' on source 'Artist' results in expression(s) instead of definitive values: ( artistid = ? OR artistid IS NULL )/,
'Expected exception on unresovable set_from_related'
;

ok( ! $artist_to_mangle->is_changed, 'Unresolvable set_from_related did not alter object' );

Expand Down
2 changes: 1 addition & 1 deletion t/relationship/custom.t
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ lives_ok {
# try to create_related a 80s cd
throws_ok {
$artist->create_related('cds_80s', { title => 'related creation 1' });
} qr/\QUnable to complete value inferrence - custom relationship 'cds_80s' on source 'Artist' returns conditions instead of values for column(s): 'year'/,
} qr/\QUnable to complete value inferrence - relationship 'cds_80s' on source 'Artist' results in expression(s) instead of definitive values: ( year < ? AND year > ? )/,
'Create failed - complex cond';

# now supply an explicit arg overwriting the ambiguous cond
Expand Down

0 comments on commit d8516e9

Please sign in to comment.