Skip to content

Commit

Permalink
Fixed #19720 -- Oracle ordering related delete regression
Browse files Browse the repository at this point in the history
When a query had a complex where condition (a condition targeting more
than the base table) a subquery was used for deletion. However, the
query had default ordering from the model's meta and Oracle doesn't
work with ordered subqueries.

The regression was caused by fast-path deletion code introduced in
1cd6e04 for fixing #18676.

Thanks to Dylan Klomparens for the report.
  • Loading branch information
akaariai committed Feb 10, 2013
1 parent 0478780 commit 8ef3235
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
2 changes: 1 addition & 1 deletion django/db/models/query.py
Expand Up @@ -539,7 +539,7 @@ def delete(self):
# Disable non-supported fields.
del_query.query.select_for_update = False
del_query.query.select_related = False
del_query.query.clear_ordering()
del_query.query.clear_ordering(force_empty=True)

collector = Collector(using=del_query.db)
collector.collect(del_query)
Expand Down
10 changes: 10 additions & 0 deletions tests/regressiontests/delete_regress/models.py
Expand Up @@ -99,3 +99,13 @@ class OrgUnit(models.Model):
class Login(models.Model):
description = models.CharField(max_length=32)
orgunit = models.ForeignKey(OrgUnit)

class House(models.Model):
address = models.CharField(max_length=32)

class OrderedPerson(models.Model):
name = models.CharField(max_length=32)
lives_in = models.ForeignKey(House)

class Meta:
ordering = ['name']
13 changes: 12 additions & 1 deletion tests/regressiontests/delete_regress/tests.py
Expand Up @@ -10,7 +10,7 @@
from .models import (Book, Award, AwardNote, Person, Child, Toy, PlayedWith,
PlayedWithNote, Email, Researcher, Food, Eaten, Policy, Version, Location,
Item, Image, File, Photo, FooFile, FooImage, FooPhoto, FooFileProxy, Login,
OrgUnit)
OrgUnit, OrderedPerson, House)


# Can't run this test under SQLite, because you can't
Expand Down Expand Up @@ -347,3 +347,14 @@ def test_ticket_19102_defer(self):
self.assertFalse(Login.objects.filter(pk=self.l1.pk).exists())
self.assertTrue(Login.objects.filter(pk=self.l2.pk).exists())


class OrderedDeleteTests(TestCase):
def test_meta_ordered_delete(self):
# When a subquery is performed by deletion code, the subquery must be
# cleared of all ordering. There was a but that caused _meta ordering
# to be used. Refs #19720.
h = House.objects.create(address='Foo')
OrderedPerson.objects.create(name='Jack', lives_in=h)
OrderedPerson.objects.create(name='Bob', lives_in=h)
OrderedPerson.objects.filter(lives_in__address='Foo').delete()
self.assertEqual(OrderedPerson.objects.count(), 0)

0 comments on commit 8ef3235

Please sign in to comment.