diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index bd649736231..edc3c4fd3e1 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -997,7 +997,7 @@ class Subquery(Expression): ) # Add table alias to the parent query's aliases to prevent # quoting. - if hasattr(resolved, 'alias'): + if hasattr(resolved, 'alias') and resolved.alias != resolved.target.model._meta.db_table: clone.queryset.query.external_aliases.add(resolved.alias) return resolved return child diff --git a/docs/releases/1.11.7.txt b/docs/releases/1.11.7.txt index fe2cf2e300f..81334533e92 100644 --- a/docs/releases/1.11.7.txt +++ b/docs/releases/1.11.7.txt @@ -16,3 +16,6 @@ Bugfixes * Made ``QuerySet.reverse()`` affect ``nulls_first`` and ``nulls_last`` (:ticket:`28722`). + +* Fixed unquoted table names in ``Subquery`` SQL when using ``OuterRef`` + (:ticket:`28689`). diff --git a/tests/expressions/models.py b/tests/expressions/models.py index 85f18fdf0e9..34fd9dff167 100644 --- a/tests/expressions/models.py +++ b/tests/expressions/models.py @@ -50,6 +50,7 @@ class Experiment(models.Model): end = models.DateTimeField() class Meta: + db_table = 'expressions_ExPeRiMeNt' ordering = ('name',) def duration(self): diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index e26b3ef6d81..ca331aeb03e 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -545,6 +545,11 @@ class BasicExpressionsTests(TestCase): expr = FuncB(FuncA()) self.assertEqual(expr.output_field, FuncA.output_field) + def test_outerref_mixed_case_table_name(self): + inner = Result.objects.filter(result_time__gte=OuterRef('experiment__assigned')) + outer = Result.objects.filter(pk__in=Subquery(inner.values('pk'))) + self.assertFalse(outer.exists()) + class IterableLookupInnerExpressionsTests(TestCase): @classmethod