X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSet.pm;h=124600b8b7549ede36bd97a8b151dc3d30d67d83;hb=d5a14c53a280677a116b2efb393853a783281b2a;hp=5c862e3427b72ab645b33201e4350cf2f0faab90;hpb=48e4eac60b37de39a225264ab16f316c407f5740;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 5c862e3..124600b 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -739,7 +739,7 @@ sub find { }++; push @unique_queries, try { - $self->_build_unique_cond ($c_name, $call_cond) + $self->_build_unique_cond ($c_name, $call_cond, 'croak_on_nulls') } || (); } @@ -797,8 +797,9 @@ sub _qualify_cond_columns { return \%aliased; } +my $callsites_warned_ucond; sub _build_unique_cond { - my ($self, $constraint_name, $extra_cond) = @_; + my ($self, $constraint_name, $extra_cond, $croak_on_null) = @_; my @c_cols = $self->result_source->unique_constraint_columns($constraint_name); @@ -810,15 +811,45 @@ sub _build_unique_cond { }; # trim out everything not in $columns - $final_cond = { map { $_ => $final_cond->{$_} } @c_cols }; - - if (my @missing = grep { ! defined $final_cond->{$_} } (@c_cols) ) { + $final_cond = { map { + exists $final_cond->{$_} + ? ( $_ => $final_cond->{$_} ) + : () + } @c_cols }; + + if (my @missing = grep + { ! ($croak_on_null ? defined $final_cond->{$_} : exists $final_cond->{$_}) } + (@c_cols) + ) { $self->throw_exception( sprintf ( "Unable to satisfy requested constraint '%s', no values for column(s): %s", $constraint_name, join (', ', map { "'$_'" } @missing), ) ); } + if ( + !$croak_on_null + and + !$ENV{DBIC_NULLABLE_KEY_NOWARN} + and + my @undefs = grep { ! defined $final_cond->{$_} } (keys %$final_cond) + ) { + my $callsite = do { + my $w; + local $SIG{__WARN__} = sub { $w = shift }; + carp; + $w + }; + + carp ( sprintf ( + "NULL/undef values supplied for requested unique constraint '%s' (NULL " + . 'values in column(s): %s). This is almost certainly not what you wanted, ' + . 'though you can set DBIC_NULLABLE_KEY_NOWARN to disable this warning.', + $constraint_name, + join (', ', map { "'$_'" } @undefs), + )) unless $callsites_warned_ucond->{$callsite}++; + } + return $final_cond; } @@ -2312,8 +2343,16 @@ sub _merge_with_rscond { while ( my($col, $value) = each %implied ) { my $vref = ref $value; - if ($vref eq 'HASH' && keys(%$value) && (keys %$value)[0] eq '=') { - $new_data{$col} = $value->{'='}; + if ($vref eq 'HASH') { + if (keys(%$value) && (keys %$value)[0] eq '=') { + $new_data{$col} = $value->{'='}; + } + # in a complex condition, set_from_related needs to override + # the columns that are involved. + elsif (!exists $data->{$col} && + !exists $data->{"$alias.$col"}) { + $self->throw_exception("unable to set_from_related via complex condition on column(s): '$col'"); + } } elsif( !$vref or $vref eq 'SCALAR' or blessed($value) ) { $new_data{$col} = $value;