From f04495521ade8a2befc1aca70dd0a2c7aad4c987 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 30 May 2017 06:40:41 -0400 Subject: [PATCH] Fixed #28199 -- Fixed Subquery generating unnecessary/invalid CAST. Thanks Simon Charette for the fix. --- django/db/models/expressions.py | 1 - docs/releases/1.11.2.txt | 3 +++ tests/expressions/models.py | 6 ++++++ tests/expressions/tests.py | 9 ++++++++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 36f22838eb6..67de5adf743 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -984,7 +984,6 @@ class Subquery(Expression): template = template or template_params.get('template', self.template) sql = template % template_params - sql = connection.ops.unification_cast_sql(self.output_field) % sql return sql, sql_params def _prepare(self, output_field): diff --git a/docs/releases/1.11.2.txt b/docs/releases/1.11.2.txt index 4dcfda7cc79..718dc386bb5 100644 --- a/docs/releases/1.11.2.txt +++ b/docs/releases/1.11.2.txt @@ -39,3 +39,6 @@ Bugfixes * Fixed ``MultipleObjectMixin.paginate_queryset()`` crash on Python 2 if the ``InvalidPage`` message contains non-ASCII (:ticket:`28204`). + +* Prevented ``Subquery`` from adding an unnecessary ``CAST`` which resulted in + invalid SQL (:ticket:`28199`). diff --git a/tests/expressions/models.py b/tests/expressions/models.py index 51042c845b1..85f18fdf0e9 100644 --- a/tests/expressions/models.py +++ b/tests/expressions/models.py @@ -1,6 +1,7 @@ """ Tests for F() query expression syntax. """ +import uuid from django.db import models @@ -79,8 +80,13 @@ class SimulationRun(models.Model): return "%s (%s to %s)" % (self.midpoint, self.start, self.end) +class UUIDPK(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4) + + class UUID(models.Model): uuid = models.UUIDField(null=True) + uuid_fk = models.ForeignKey(UUIDPK, models.CASCADE, null=True) def __str__(self): return "%s" % self.uuid diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 5483a17fd19..ed3e2ce6288 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -24,7 +24,8 @@ from django.test import ( from django.test.utils import Approximate from .models import ( - UUID, Company, Employee, Experiment, Number, Result, SimulationRun, Time, + UUID, UUIDPK, Company, Employee, Experiment, Number, Result, SimulationRun, + Time, ) @@ -479,6 +480,12 @@ class BasicExpressionsTests(TestCase): subquery_test2 = Company.objects.filter(pk=Subquery(small_companies.filter(num_employees=3))) self.assertCountEqual(subquery_test2, [self.foobar_ltd]) + def test_uuid_pk_subquery(self): + u = UUIDPK.objects.create() + UUID.objects.create(uuid_fk=u) + qs = UUIDPK.objects.filter(id__in=Subquery(UUID.objects.values('uuid_fk__id'))) + self.assertCountEqual(qs, [u]) + def test_nested_subquery(self): inner = Company.objects.filter(point_of_contact=OuterRef('pk')) outer = Employee.objects.annotate(is_point_of_contact=Exists(inner))