Fixed #29545 -- Fixed using filter lookups againts nested subquery expressions.

Made sql.Where resolve lhs of its child nodes. This is necessary to
allow filter lookups against nested subquery expressions to properly
resolve their OuterRefs to Cols.

Thanks Oskar Persson for the simplified test case.
This commit is contained in:
Simon Charette 2019-08-15 23:20:57 -04:00 committed by Mariusz Felisiak
parent 7203efb799
commit 8b4a43dda7
2 changed files with 21 additions and 5 deletions

View File

@ -184,18 +184,20 @@ class WhereNode(tree.Node):
return any(child.is_summary for child in self.children) return any(child.is_summary for child in self.children)
@staticmethod @staticmethod
def _resolve_rhs(rhs, query, *args, **kwargs): def _resolve_leaf(expr, query, *args, **kwargs):
if hasattr(rhs, 'resolve_expression'): if hasattr(expr, 'resolve_expression'):
rhs = rhs.resolve_expression(query, *args, **kwargs) expr = expr.resolve_expression(query, *args, **kwargs)
return rhs return expr
@classmethod @classmethod
def _resolve_node(cls, node, query, *args, **kwargs): def _resolve_node(cls, node, query, *args, **kwargs):
if hasattr(node, 'children'): if hasattr(node, 'children'):
for child in node.children: for child in node.children:
cls._resolve_node(child, query, *args, **kwargs) cls._resolve_node(child, query, *args, **kwargs)
if hasattr(node, 'lhs'):
node.lhs = cls._resolve_leaf(node.lhs, query, *args, **kwargs)
if hasattr(node, 'rhs'): if hasattr(node, 'rhs'):
node.rhs = cls._resolve_rhs(node.rhs, query, *args, **kwargs) node.rhs = cls._resolve_leaf(node.rhs, query, *args, **kwargs)
def resolve_expression(self, *args, **kwargs): def resolve_expression(self, *args, **kwargs):
clone = self.clone() clone = self.clone()

View File

@ -942,3 +942,17 @@ class LookupTests(TestCase):
pk_exists=Exists(qs), pk_exists=Exists(qs),
) )
self.assertCountEqual(seasons, Season.objects.all()) self.assertCountEqual(seasons, Season.objects.all())
def test_nested_outerref_lhs(self):
tag = Tag.objects.create(name=self.au1.alias)
tag.articles.add(self.a1)
qs = Tag.objects.annotate(
has_author_alias_match=Exists(
Article.objects.annotate(
author_exists=Exists(
Author.objects.filter(alias=OuterRef(OuterRef('name')))
),
).filter(author_exists=True)
),
)
self.assertEqual(qs.get(has_author_alias_match=True), tag)