diff options
| author | Anssi Kääriäinen <akaariai@gmail.com> | 2014-10-07 16:07:46 +0300 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2014-11-20 13:53:28 -0500 |
| commit | 01f2cf2aecc932d43b20b55fc19a8fa440457b5f (patch) | |
| tree | 9bcbdba8451ca6bb5a1ffa8471aca328c43c510d /tests | |
| parent | 2e2607870d6201f305e56ab4117bbce2fef63f17 (diff) | |
[1.7.x] Fixed #23605 -- Fixed nested subquery regression
Added relabeled_clone() method to sql.Query to fix the problem. It
manifested itself in rare cases where at least double nested subquery's
filter condition might target non-existing alias.
Thanks to Trac alias ris for reporting the problem.
Backport of 5c481db29572a387651681b43d5d4523f96b3793 from master
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/queries/models.py | 15 | ||||
| -rw-r--r-- | tests/queries/tests.py | 39 |
2 files changed, 53 insertions, 1 deletions
diff --git a/tests/queries/models.py b/tests/queries/models.py index 604eed5f07..6e6a0ce5e1 100644 --- a/tests/queries/models.py +++ b/tests/queries/models.py @@ -675,3 +675,18 @@ class Student(models.Model): class Classroom(models.Model): school = models.ForeignKey(School) students = models.ManyToManyField(Student, related_name='classroom') + + +class Ticket23605A(models.Model): + pass + + +class Ticket23605B(models.Model): + modela_fk = models.ForeignKey(Ticket23605A) + modelc_fk = models.ForeignKey("Ticket23605C") + field_b0 = models.IntegerField(null=True) + field_b1 = models.BooleanField(default=False) + + +class Ticket23605C(models.Model): + field_c0 = models.FloatField() diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 0fff68b21f..f6162508b9 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -27,7 +27,8 @@ from .models import ( BaseA, FK1, Identifier, Program, Channel, Page, Paragraph, Chapter, Book, MyObject, Order, OrderItem, SharedConnection, Task, Staff, StaffUser, CategoryRelationship, Ticket21203Parent, Ticket21203Child, Person, - Company, Employment, CustomPk, CustomPkTag, Classroom, School, Student) + Company, Employment, CustomPk, CustomPkTag, Classroom, School, Student, + Ticket23605A, Ticket23605B, Ticket23605C) class BaseQuerysetTest(TestCase): @@ -3391,3 +3392,39 @@ class Ticket22429Tests(TestCase): queryset = Student.objects.filter(~Q(classroom__school=F('school'))) self.assertQuerysetEqual(queryset, [st2], lambda x: x) + + +class Ticket23605Tests(TestCase): + def test_ticket_23605(self): + # Test filtering on a complicated q-object from ticket's report. + # The query structure is such that we have multiple nested subqueries. + # The original problem was that the inner queries weren't relabeled + # correctly. + a1 = Ticket23605A.objects.create() + a2 = Ticket23605A.objects.create() + c1 = Ticket23605C.objects.create(field_c0=10000.0) + Ticket23605B.objects.create( + field_b0=10000.0, field_b1=True, + modelc_fk=c1, modela_fk=a1) + complex_q = Q(pk__in=Ticket23605A.objects.filter( + Q( + # True for a1 as field_b0 = 10000, field_c0=10000 + # False for a2 as no ticket23605b found + ticket23605b__field_b0__gte=1000000 / + F("ticket23605b__modelc_fk__field_c0") + ) & + # True for a1 (field_b1=True) + Q(ticket23605b__field_b1=True) & + ~Q(ticket23605b__pk__in=Ticket23605B.objects.filter( + ~( + # Same filters as above commented filters, but + # double-negated (one for Q() above, one for + # parentheses). So, again a1 match, a2 not. + Q(field_b1=True) & + Q(field_b0__gte=1000000 / F("modelc_fk__field_c0")) + ) + ))).filter(ticket23605b__field_b1=True)) + qs1 = Ticket23605A.objects.filter(complex_q) + self.assertQuerysetEqual(qs1, [a1], lambda x: x) + qs2 = Ticket23605A.objects.exclude(complex_q) + self.assertQuerysetEqual(qs2, [a2], lambda x: x) |
