From c67ea79aa981ae82595d89f8018a41fcd842e7c9 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Sun, 26 Feb 2023 13:43:00 +0100 Subject: [PATCH] Fixed #34368 -- Made subquery raise NotSupportedError when referencing outer window expression. Regression in f387d024fc75569d2a4a338bfda76cc2f328f627. Co-authored-by: Jannis Vajen --- django/db/models/expressions.py | 5 +++++ django/db/models/sql/compiler.py | 2 +- tests/expressions_window/tests.py | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 2d8a5c5919..d412e7657e 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -857,6 +857,11 @@ class ResolvedOuterRef(F): def resolve_expression(self, *args, **kwargs): col = super().resolve_expression(*args, **kwargs) + if col.contains_over_clause: + raise NotSupportedError( + f"Referencing outer query window expression is not supported: " + f"{self.name}." + ) # FIXME: Rename possibly_multivalued to multivalued and fix detection # for non-multivalued JOINs (e.g. foreign key fields). This should take # into account only many-to-many and one-to-many relationships. diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index e1a240dec3..07393e7605 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -676,7 +676,7 @@ class SQLCompiler: ) ) inner_query_compiler = inner_query.get_compiler( - self.using, elide_empty=self.elide_empty + self.using, connection=self.connection, elide_empty=self.elide_empty ) inner_sql, inner_params = inner_query_compiler.as_sql( # The limits must be applied to the outer query to avoid pruning diff --git a/tests/expressions_window/tests.py b/tests/expressions_window/tests.py index 027fc9c25c..3a02a36707 100644 --- a/tests/expressions_window/tests.py +++ b/tests/expressions_window/tests.py @@ -1587,6 +1587,25 @@ class WindowUnsupportedTests(TestCase): dense_rank=Window(expression=DenseRank()) ).get() + def test_filter_subquery(self): + qs = Employee.objects.annotate( + department_salary_rank=Window( + Rank(), partition_by="department", order_by="-salary" + ) + ) + msg = ( + "Referencing outer query window expression is not supported: " + "department_salary_rank." + ) + with self.assertRaisesMessage(NotSupportedError, msg): + qs.annotate( + employee_name=Subquery( + Employee.objects.filter( + age=OuterRef("department_salary_rank") + ).values("name")[:1] + ) + ) + class NonQueryWindowTests(SimpleTestCase): def test_window_repr(self):