Skip to content

Commit

Permalink
Fix oversight in subqueried MySQL update/delete
Browse files Browse the repository at this point in the history
  • Loading branch information
ribasushi committed Apr 9, 2013
1 parent 5a1dea8 commit f4fdfd6
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 9 deletions.
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/DBIx/Class/Storage/DBI/mysql.pm
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ sub _prep_for_execute {
}

local $sm->{_modification_target_referenced_re} =
qr/ (?<!DELETE) [\s\)] FROM \s (?: \` \Q$target_name\E \` | \Q$target_name\E ) [\s\(] /xi
qr/ (?<!DELETE) [\s\)] (?: FROM | JOIN ) \s (?: \` \Q$target_name\E \` | \Q$target_name\E ) [\s\(] /xi
if $target_name;

$self->next::method(@_);
Expand Down
28 changes: 21 additions & 7 deletions t/71mysql.t
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
27 changes: 26 additions & 1 deletion t/sqlmaker/mysql.t
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit f4fdfd6

Please sign in to comment.