Fixed #25882 -- Prevented fast deletes matching no rows from crashing on MySQL.

Thanks to Trac aliases gerricom for the report, raphaelmerx for the
attempts to reproduce and Sergey Fedoseev and Tim for the review.

Refs #16891
This commit is contained in:
Simon Charette 2015-12-13 23:46:41 -05:00
parent 5233b70070
commit 8035cee922
3 changed files with 16 additions and 1 deletions

View File

@ -68,7 +68,7 @@ class DeleteQuery(Query):
# We can't do the delete using subquery. # We can't do the delete using subquery.
values = list(query.values_list('pk', flat=True)) values = list(query.values_list('pk', flat=True))
if not values: if not values:
return return 0
return self.delete_batch(values, using) return self.delete_batch(values, using)
else: else:
innerq.clear_select_clause() innerq.clear_select_clause()

View File

@ -34,3 +34,6 @@ Bugfixes
created by ``startapp`` on Python 2 (:ticket:`25909`). Add this line to your created by ``startapp`` on Python 2 (:ticket:`25909`). Add this line to your
own ``apps.py`` files created using Django 1.9 if you want your migrations own ``apps.py`` files created using Django 1.9 if you want your migrations
to work on both Python 2 and Python 3. to work on both Python 2 and Python 3.
* Prevented ``QuerySet.delete()`` from crashing on MySQL when querying across
relations (:ticket`25882`).

View File

@ -503,3 +503,15 @@ class FastDeleteTests(TestCase):
# that + fast delete of the related objs. # that + fast delete of the related objs.
self.assertNumQueries(2, a.delete) self.assertNumQueries(2, a.delete)
self.assertEqual(User.objects.count(), 0) self.assertEqual(User.objects.count(), 0)
def test_fast_delete_empty_no_update_can_self_select(self):
"""
#25932 - Fast deleting on backends that don't have the
`no_update_can_self_select` feature should work even if the specified
filter doesn't match any row.
"""
with self.assertNumQueries(1):
self.assertEqual(
User.objects.filter(avatar__desc='missing').delete(),
(0, {'delete.User': 0})
)