Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #19720 -- Oracle ordering related delete regression

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...
commit 8ef3235034a1a7616714a5d61486dc68536f74ee 1 parent 0478780
@akaariai akaariai authored
View
2  django/db/models/query.py
@@ -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)
View
10 tests/regressiontests/delete_regress/models.py
@@ -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']
View
13 tests/regressiontests/delete_regress/tests.py
@@ -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
@@ -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)
Please sign in to comment.
Something went wrong with that request. Please try again.