Commit 8ef32350 authored by Anssi Kääriäinen's avatar Anssi Kääriäinen
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
1cd6e04c for fixing #18676.

Thanks to Dylan Klomparens for the report.
parent 0478780b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -539,7 +539,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)
+10 −0
Original line number Diff line number Diff line
@@ -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']
+12 −1
Original line number Diff line number Diff line
@@ -10,7 +10,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
@@ -347,3 +347,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)