From: Peter Rabbitson Date: Wed, 20 Jan 2010 07:32:39 +0000 (+0000) Subject: Fix minor RSC bug X-Git-Tag: v0.08116~44 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=66e33361ebc5e747a6ce85912efd2c20f5c9f0e3 Fix minor RSC bug --- diff --git a/Changes b/Changes index d282eda..a62dd5c 100644 --- a/Changes +++ b/Changes @@ -12,6 +12,8 @@ Revision history for DBIx::Class - Stop the SQLT parser from auto-adding indexes identical to the Primary Key - Schema POD improvement for dclone + - Fix ResultSetColumn improperly selecting more than the requested + column when +columns/+select is present - Fix regression in context sensitiveness of deployment_statements - Fix regression resulting in overcomplicated query on search_related from prefetching resultsets diff --git a/lib/DBIx/Class/ResultSetColumn.pm b/lib/DBIx/Class/ResultSetColumn.pm index 0057abf..14b35f7 100644 --- a/lib/DBIx/Class/ResultSetColumn.pm +++ b/lib/DBIx/Class/ResultSetColumn.pm @@ -42,24 +42,26 @@ sub new { my ($class, $rs, $column) = @_; $class = ref $class if ref $class; - $rs->throw_exception("column must be supplied") unless $column; + $rs->throw_exception('column must be supplied') unless $column; my $orig_attrs = $rs->_resolved_attrs; my $new_parent_rs = $rs->search_rs; + my $new_attrs = $new_parent_rs->{attrs} ||= {}; + + # since what we do is actually chain to the original resultset, we need to throw + # away all selectors (otherwise they'll chain) + delete $new_attrs->{$_} for (qw/columns +columns select +select as +as cols include_columns/); # prefetch causes additional columns to be fetched, but we can not just make a new # rs via the _resolved_attrs trick - we need to retain the separation between # +select/+as and select/as. At the same time we want to preserve any joins that the # prefetch would otherwise generate. - - my $new_attrs = $new_parent_rs->{attrs} ||= {}; $new_attrs->{join} = $rs->_merge_attr( delete $new_attrs->{join}, delete $new_attrs->{prefetch} ); # If $column can be found in the 'as' list of the parent resultset, use the # corresponding element of its 'select' list (to keep any custom column # definition set up with 'select' or '+select' attrs), otherwise use $column # (to create a new column definition on-the-fly). - my $as_list = $orig_attrs->{as} || []; my $select_list = $orig_attrs->{select} || []; my $as_index = List::Util::first { ($as_list->[$_] || "") eq $column } 0..$#$as_list; diff --git a/t/88result_set_column.t b/t/88result_set_column.t index 615d8aa..f3d31d4 100644 --- a/t/88result_set_column.t +++ b/t/88result_set_column.t @@ -6,6 +6,7 @@ use Test::Warn; use Test::Exception; use lib qw(t/lib); use DBICTest; +use DBIC::SqlMakerTest; my $schema = DBICTest->init_schema(); @@ -61,6 +62,16 @@ my $psrs = $schema->resultset('CD')->search({}, lives_ok(sub { $psrs->get_column('count')->next }, '+select/+as additional column "count" present (scalar)'); dies_ok(sub { $psrs->get_column('noSuchColumn')->next }, '+select/+as nonexistent column throws exception'); +# test +select/+as for overriding a column +$psrs = $schema->resultset('CD')->search({}, + { + 'select' => \"'The Final Countdown'", + 'as' => 'title' + } +); +is($psrs->get_column('title')->next, 'The Final Countdown', '+select/+as overridden column "title"'); + + # test +select/+as for multiple columns $psrs = $schema->resultset('CD')->search({}, { @@ -71,14 +82,28 @@ $psrs = $schema->resultset('CD')->search({}, lives_ok(sub { $psrs->get_column('count')->next }, '+select/+as multiple additional columns, "count" column present'); lives_ok(sub { $psrs->get_column('addedtitle')->next }, '+select/+as multiple additional columns, "addedtitle" column present'); -# test +select/+as for overriding a column -$psrs = $schema->resultset('CD')->search({}, - { - 'select' => \"'The Final Countdown'", - 'as' => 'title' - } +# test that +select/+as specs do not leak +is_same_sql_bind ( + $psrs->get_column('year')->as_query, + '(SELECT me.year FROM cd me)', + [], + 'Correct SQL for get_column/as' ); -is($psrs->get_column('title')->next, 'The Final Countdown', '+select/+as overridden column "title"'); + +is_same_sql_bind ( + $psrs->get_column('addedtitle')->as_query, + '(SELECT me.title FROM cd me)', + [], + 'Correct SQL for get_column/+as col' +); + +is_same_sql_bind ( + $psrs->get_column('count')->as_query, + '(SELECT COUNT(*) FROM cd me)', + [], + 'Correct SQL for get_column/+as func' +); + { my $rs = $schema->resultset("CD")->search({}, { prefetch => 'artist' });