From: Peter Rabbitson Date: Mon, 31 May 2010 22:20:38 +0000 (+0000) Subject: Fix update/delete on prefetching resultsets X-Git-Tag: v0.08122~40^2~2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=887d8da0864e028f457ce5c6abaccb2d7160698b Fix update/delete on prefetching resultsets --- diff --git a/Changes b/Changes index 63a480c..3fb0f4d 100644 --- a/Changes +++ b/Changes @@ -34,6 +34,8 @@ Revision history for DBIx::Class - update() on row not in_storage no longer throws an exception if there are no dirty columns to update (fixes cascaded update annoyances) + - update()/delete() on prefetching resultsets no longer results + in malformed SQL (some $rs attributes were erroneously left in) - Fix dbicadmin to allow deploy() on non-versioned schema - Fix dbicadmin to respect sql_dir on upgrade() (RT#57732) - Update Schema::Versioned to respect hashref style of diff --git a/Makefile.PL b/Makefile.PL index 01ef651..d2cd848 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -44,7 +44,7 @@ my $runtime_requires = { 'MRO::Compat' => '0.09', 'Module::Find' => '0.06', 'Path::Class' => '0.18', - 'SQL::Abstract' => '1.66', + 'SQL::Abstract' => '1.67', 'SQL::Abstract::Limit' => '0.13', 'Sub::Name' => '0.04', 'Data::Dumper::Concise' => '1.000', diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index a27f8a2..cba01bc 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -197,7 +197,6 @@ sub new { my $self = { _source_handle => $source, cond => $attrs->{where}, - count => undef, pager => undef, attrs => $attrs }; @@ -1434,7 +1433,8 @@ sub _rs_update_delete { # make a new $rs selecting only the PKs (that's all we really need) my $attrs = $self->_resolved_attrs_copy; - delete $attrs->{$_} for qw/collapse select as/; + + delete $attrs->{$_} for qw/collapse _collapse_order_by select _prefetch_select as/; $attrs->{columns} = [ map { "$attrs->{alias}.$_" } ($self->result_source->_pri_cols) ]; if ($needs_group_by_subq) { @@ -1468,7 +1468,6 @@ sub _rs_update_delete { } my $subrs = (ref $self)->new($rsrc, $attrs); - return $self->result_source->storage->_subq_update_delete($subrs, $op, $values); } else { diff --git a/t/resultset/update_delete.t b/t/resultset/update_delete.t index 542ea07..5cd7071 100644 --- a/t/resultset/update_delete.t +++ b/t/resultset/update_delete.t @@ -5,6 +5,8 @@ use lib qw(t/lib); use Test::More; use Test::Exception; use DBICTest; +use DBIC::DebugObj; +use DBIC::SqlMakerTest; my $schema = DBICTest->init_schema(); @@ -105,7 +107,6 @@ is_deeply ( ); $sub_rs->delete; - is ($tkfks->count, $tkfk_cnt -= 2, 'Only two rows deleted'); # make sure limit-only deletion works @@ -113,4 +114,26 @@ cmp_ok ($tkfk_cnt, '>', 1, 'More than 1 row left'); $tkfks->search ({}, { rows => 1 })->delete; is ($tkfks->count, $tkfk_cnt -= 1, 'Only one row deleted'); + +# Make sure prefetch is properly stripped too +# check with sql-equality, as sqlite will accept bad sql just fine +my ($sql, @bind); +my $orig_debugobj = $schema->storage->debugobj; +my $orig_debug = $schema->storage->debug; + +$schema->storage->debugobj (DBIC::DebugObj->new (\$sql, \@bind) ); +$schema->storage->debug (1); +$schema->resultset('CD')->search( + { year => { '!=' => 2010 } }, + { prefetch => 'liner_notes' }, +)->delete; + +is_same_sql_bind ( + $sql, + \@bind, + 'DELETE FROM cd WHERE ( cdid IN ( SELECT me.cdid FROM cd me WHERE ( year != ? ) GROUP BY me.cdid ) )', + ["'2010'"], + 'Update on prefetching resultset strips prefetch correctly' +); + done_testing;