summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Schinckel <matt@schinckel.net>2017-02-25 21:11:56 +1030
committerTim Graham <timograham@gmail.com>2017-03-01 08:21:12 -0500
commit2864bb3ba6576cbd2676052344a445a6616a6679 (patch)
treecaa6abaf332dab6b157f59097a30078bf64758b7
parent3a3145bfcd7a1de1e7cda2d3f2ba61a90d34cf11 (diff)
[1.11.x] Fixed #27862 -- Fixed incorrectly quoted table aliases in Subquery SQL.
Add aliases from resolved querysets to the parent query's external aliases to prevent those aliases from being quoted. Thanks to Vasily Stepanov for the report and Tim Graham for the review. Backport of f48bc7c3dbd204eefb3c19016b1e4906ac26bee3 from master
-rw-r--r--django/db/models/expressions.py7
-rw-r--r--tests/expressions/tests.py9
2 files changed, 15 insertions, 1 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 01f1333651..a05a1b35ab 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -933,10 +933,15 @@ class Subquery(Expression):
def resolve(child):
if hasattr(child, 'resolve_expression'):
- return child.resolve_expression(
+ resolved = child.resolve_expression(
query=query, allow_joins=allow_joins, reuse=reuse,
summarize=summarize, for_save=for_save,
)
+ # Add table alias to the parent query's aliases to prevent
+ # quoting.
+ if hasattr(resolved, 'alias'):
+ clone.queryset.query.external_aliases.add(resolved.alias)
+ return resolved
return child
resolve_all(clone.queryset.query.where)
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
index f6c1c273b7..6e5cf58295 100644
--- a/tests/expressions/tests.py
+++ b/tests/expressions/tests.py
@@ -517,6 +517,15 @@ class BasicExpressionsTests(TestCase):
[{'salary': 10, 'total_employees': 2300}, {'salary': 20, 'total_employees': 35}],
)
+ def test_subquery_references_joined_table_twice(self):
+ inner = Company.objects.filter(
+ num_chairs__gte=OuterRef('ceo__salary'),
+ num_employees__gte=OuterRef('point_of_contact__salary'),
+ )
+ # Another contrived example (there is no need to have a subquery here)
+ outer = Company.objects.filter(pk__in=Subquery(inner.values('pk')))
+ self.assertFalse(outer.exists())
+
class IterableLookupInnerExpressionsTests(TestCase):
@classmethod