summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2013-02-10 19:49:28 +0200
committerAnssi Kääriäinen <akaariai@gmail.com>2013-02-10 19:58:22 +0200
commitb18ad807e0b7f34df4e4b319af128883a54c03bd (patch)
treeeeab95b3761f5482586d77c98e4b6cc14009bfb1
parentd8e68f421e676de16953090c187e165a6c1ed900 (diff)
[1.5.x] 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 1cd6e04cd4f768bcd4385b75de433d497d938f82 for fixing #18676. Thanks to Dylan Klomparens for the report. Backpatch of 8ef3235034a1a7616714a5d61486dc68536f74ee
-rw-r--r--django/db/models/query.py2
-rw-r--r--tests/regressiontests/delete_regress/models.py10
-rw-r--r--tests/regressiontests/delete_regress/tests.py13
3 files changed, 23 insertions, 2 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 6b628e81cb..952739e939 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -530,7 +530,7 @@ class QuerySet(object):
# 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)
diff --git a/tests/regressiontests/delete_regress/models.py b/tests/regressiontests/delete_regress/models.py
index dbe383fb41..3632a7dbc1 100644
--- a/tests/regressiontests/delete_regress/models.py
+++ b/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']
diff --git a/tests/regressiontests/delete_regress/tests.py b/tests/regressiontests/delete_regress/tests.py
index f94bb2f20c..1bc4e781fe 100644
--- a/tests/regressiontests/delete_regress/tests.py
+++ b/tests/regressiontests/delete_regress/tests.py
@@ -9,7 +9,7 @@ from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
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
@@ -355,3 +355,14 @@ class Ticket19102Tests(TestCase):
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)