Fix minor RSC bug
Peter Rabbitson [Wed, 20 Jan 2010 07:32:39 +0000 (07:32 +0000)]
Changes
lib/DBIx/Class/ResultSetColumn.pm
t/88result_set_column.t

diff --git a/Changes b/Changes
index d282eda..a62dd5c 100644 (file)
--- 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
index 0057abf..14b35f7 100644 (file)
@@ -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;
index 615d8aa..f3d31d4 100644 (file)
@@ -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' });