From: Peter Rabbitson Date: Tue, 27 Sep 2016 17:35:15 +0000 (+0200) Subject: Fix func_rs() and as_subselect_rs() to start behaving as advertised X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=6c5aa1fbffdc9e5679d2f68780b11a9569ec1993 Fix func_rs() and as_subselect_rs() to start behaving as advertised No idea how it never got noticed, but both have been broken since the very first commits that introduced the methods ( 4fa7bc22 / e4bb6727 ). While changing them 7 years later is a rather serious modification of behavior, the old way never worked without users having to force-scalar each call site. If someone has been relying on e.g. [ func_rs(...) ] to return actual result objects instead of the resultset instance - things will blow up rather quickly and loudly (aside from the carp()-ed warning encouraging users to switch to scalar ctx explicitly) [ func( ... ) ] of course continues to behave like before (directly returning raw values off the cursor... sigh) --- diff --git a/Changes b/Changes index 6a63e5b..fabe41d 100644 --- a/Changes +++ b/Changes @@ -27,6 +27,8 @@ Revision history for DBIx::Class an underlying search_rs(), as by design these arguments would be used only on the first call to ->related_resultset(), and ignored afterwards. Instead an exception (detailing the fix) is thrown. + - Change func_rs() and as_subselect_rs() to properly ignore list + context (i.e. wantarray). Both were implemented broken from day 1 :/ - Increased checking for the correctness of the is_nullable attribute within the prefetch result parser may highlight previously unknown mismatches between your codebase and data source diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 2d6ea30..a274ee7 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -3504,6 +3504,21 @@ 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 $alias = $self->current_source_alias; @@ -3516,7 +3531,7 @@ sub as_subselect_rs { delete $fresh_rs->{cond}; delete @{$fresh_rs->{attrs}}{qw/where bind/}; - return $fresh_rs->search( {}, { + $fresh_rs->search_rs( {}, { from => [{ $alias => $self->as_query, -alias => $alias, diff --git a/lib/DBIx/Class/ResultSetColumn.pm b/lib/DBIx/Class/ResultSetColumn.pm index a514139..5b510de 100644 --- a/lib/DBIx/Class/ResultSetColumn.pm +++ b/lib/DBIx/Class/ResultSetColumn.pm @@ -448,7 +448,21 @@ sub func_rs { $rs = $rs->as_subselect_rs; } - $rs->search( undef, { + # FIXME - remove at some point in the future (2018-ish) + wantarray + and + carp_unique( + 'Starting with DBIC@0.082900 func_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 + ; + + $rs->search_rs( undef, { columns => { $self->{_as} => { $function => $select } } } ); } diff --git a/t/88result_set_column.t b/t/88result_set_column.t index f27c5dd..7abf670 100644 --- a/t/88result_set_column.t +++ b/t/88result_set_column.t @@ -40,6 +40,13 @@ while (my $r = $rs_title->next) { is_deeply (\@all_titles, \@nexted_titles, 'next works'); +my @list_ctx; +warnings_exist { + @list_ctx = $rs_year->func_rs('DISTINCT'); +} [qr/\Qfunc_rs() always returns a ResultSet instance regardless of calling context/]; +is( scalar @list_ctx, 1, 'wantarray context does not affect func_rs'); +isa_ok( $list_ctx[0], 'DBIx::Class::ResultSet' ); +isa_ok( scalar( $rs_year->func_rs('DISTINCT') ), 'DBIx::Class::ResultSet' ); is_deeply( [ sort $rs_year->func('DISTINCT') ], [ 1997, 1998, 1999, 2001 ], "wantarray context okay"); ok ($max_year->next == $rs_year->max, q/get_column (\'FUNC') ok/);