From: Peter Rabbitson Date: Tue, 9 Apr 2013 13:15:12 +0000 (+0200) Subject: Fix oversight in subqueried MySQL update/delete X-Git-Tag: v0.08250~36 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=f4fdfd698d337ae49dc1ccd93e751e04dcde045c Fix oversight in subqueried MySQL update/delete --- diff --git a/Changes b/Changes index 9a3ce19..416776c 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,10 @@ Revision history for DBIx::Class + * Fixes + - Fix update/delete operations on resultsets *joining* the updated + table failing on MySQL. Resolves oversights in the fixes for + RT#81378 and RT#81897 + 0.08210 2013-04-04 15:30 (UTC) * New Features / Changes - Officially deprecate the 'cols' and 'include_columns' resultset diff --git a/lib/DBIx/Class/Storage/DBI/mysql.pm b/lib/DBIx/Class/Storage/DBI/mysql.pm index 3ace8e2..a2aa2fc 100644 --- a/lib/DBIx/Class/Storage/DBI/mysql.pm +++ b/lib/DBIx/Class/Storage/DBI/mysql.pm @@ -78,7 +78,7 @@ sub _prep_for_execute { } local $sm->{_modification_target_referenced_re} = - qr/ (?next::method(@_); diff --git a/t/71mysql.t b/t/71mysql.t index de1e2fd..e492417 100644 --- a/t/71mysql.t +++ b/t/71mysql.t @@ -319,20 +319,34 @@ NULLINSEARCH: { ); } - my $ac = $schema->resultset('Artist')->count_rs; - my $old_count = $ac->next; - $ac->reset; + is ($rs->count, 10, '10 artists present'); my $orig_debug = $schema->storage->debug; $schema->storage->debug(1); - my $query_count = 0; + my $query_count; $schema->storage->debugcb(sub { $query_count++ }); + + $query_count = 0; $complex_rs->delete; - $schema->storage->debugcb(undef); - $schema->storage->debug($orig_debug); is ($query_count, 1, 'One delete query fired'); - is ($old_count - $ac->next, 10, '10 Artists correctly deleted'); + is ($rs->count, 0, '10 Artists correctly deleted'); + + $rs->create({ + name => 'baby_with_cd', + cds => [ { title => 'babeeeeee', year => 2013 } ], + }); + is ($rs->count, 1, 'Artist with cd created'); + + $query_count = 0; + $schema->resultset('CD')->search_related('artist', + { 'artist.name' => { -like => 'baby_with_%' } } + )->delete; + is ($query_count, 1, 'And one more delete query fired'); + is ($rs->count, 0, 'Artist with cd deleted'); + + $schema->storage->debugcb(undef); + $schema->storage->debug($orig_debug); } ZEROINSEARCH: { diff --git a/t/sqlmaker/mysql.t b/t/sqlmaker/mysql.t index 9de4c7f..b00691f 100644 --- a/t/sqlmaker/mysql.t +++ b/t/sqlmaker/mysql.t @@ -49,7 +49,7 @@ bless ( $schema->storage, 'DBIx::Class::Storage::DBI::mysql' ); 'Correct delete-SQL with double-wrapped subquery', ); - # and a really contrived example (we test it live in t/71mysql.t) + # and a couple of really contrived examples (we test them live in t/71mysql.t) my $rs = $schema->resultset('Artist')->search({ name => { -like => 'baby_%' } }); my ($count_sql, @count_bind) = @${$rs->count_rs->as_query}; eval { @@ -86,6 +86,31 @@ bless ( $schema->storage, 'DBIx::Class::Storage::DBI::mysql' ); [ ("'baby_%'") x 2 ], ); + eval { + $schema->resultset('CD')->search_related('artist', + { 'artist.name' => { -like => 'baby_with_%' } } + )->delete + }; + + is_same_sql_bind ( + $sql, + \@bind, + q( + DELETE FROM `artist` + WHERE `artistid` IN ( + SELECT * + FROM ( + SELECT `artist`.`artistid` + FROM cd `me` + INNER JOIN `artist` `artist` + ON `artist`.`artistid` = `me`.`artist` + WHERE `artist`.`name` LIKE ? + ) `_forced_double_subquery` + ) + ), + [ "'baby_with_%'" ], + ); + $schema->storage->debugobj ($orig_debugobj); $schema->storage->debug ($orig_debug); }