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
1cd6e04cd4
for fixing #18676.
Thanks to Dylan Klomparens for the report.
This commit is contained in:
parent
0478780b8e
commit
8ef3235034
|
@ -539,7 +539,7 @@ class QuerySet(object):
|
||||||
# Disable non-supported fields.
|
# Disable non-supported fields.
|
||||||
del_query.query.select_for_update = False
|
del_query.query.select_for_update = False
|
||||||
del_query.query.select_related = 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 = Collector(using=del_query.db)
|
||||||
collector.collect(del_query)
|
collector.collect(del_query)
|
||||||
|
|
|
@ -99,3 +99,13 @@ class OrgUnit(models.Model):
|
||||||
class Login(models.Model):
|
class Login(models.Model):
|
||||||
description = models.CharField(max_length=32)
|
description = models.CharField(max_length=32)
|
||||||
orgunit = models.ForeignKey(OrgUnit)
|
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']
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
|
||||||
from .models import (Book, Award, AwardNote, Person, Child, Toy, PlayedWith,
|
from .models import (Book, Award, AwardNote, Person, Child, Toy, PlayedWith,
|
||||||
PlayedWithNote, Email, Researcher, Food, Eaten, Policy, Version, Location,
|
PlayedWithNote, Email, Researcher, Food, Eaten, Policy, Version, Location,
|
||||||
Item, Image, File, Photo, FooFile, FooImage, FooPhoto, FooFileProxy, Login,
|
Item, Image, File, Photo, FooFile, FooImage, FooPhoto, FooFileProxy, Login,
|
||||||
OrgUnit)
|
OrgUnit, OrderedPerson, House)
|
||||||
|
|
||||||
|
|
||||||
# Can't run this test under SQLite, because you can't
|
# Can't run this test under SQLite, because you can't
|
||||||
|
@ -347,3 +347,14 @@ class Ticket19102Tests(TestCase):
|
||||||
self.assertFalse(Login.objects.filter(pk=self.l1.pk).exists())
|
self.assertFalse(Login.objects.filter(pk=self.l1.pk).exists())
|
||||||
self.assertTrue(Login.objects.filter(pk=self.l2.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)
|
||||||
|
|
Loading…
Reference in New Issue