summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomáš Ehrlich <tomas.ehrlich@gmail.com>2018-03-01 08:55:05 +0100
committerTim Graham <timograham@gmail.com>2018-03-01 10:24:14 -0500
commitfa352626c2a80bcdcd0fc6492b5fd5130490f05e (patch)
tree52004cfda1e319a800b4550cc3296ad683b0bec4
parentba4a9862407c8e8574c60b9f911f6b09aff1fa12 (diff)
Fixed #29172 -- Fixed crash with Window expression in a subquery.
-rw-r--r--django/db/models/expressions.py6
-rw-r--r--docs/releases/2.0.3.txt3
-rw-r--r--tests/expressions_window/tests.py13
3 files changed, 20 insertions, 2 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 307ee97db5..4ce869d80a 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -315,8 +315,10 @@ class BaseExpression:
def relabeled_clone(self, change_map):
clone = self.copy()
- clone.set_source_expressions(
- [e.relabeled_clone(change_map) for e in self.get_source_expressions()])
+ clone.set_source_expressions([
+ e.relabeled_clone(change_map) if e is not None else None
+ for e in self.get_source_expressions()
+ ])
return clone
def copy(self):
diff --git a/docs/releases/2.0.3.txt b/docs/releases/2.0.3.txt
index 42020a6923..f4f30b5a30 100644
--- a/docs/releases/2.0.3.txt
+++ b/docs/releases/2.0.3.txt
@@ -25,3 +25,6 @@ Bugfixes
* Fixed a regression where a ``When()`` expression with a list argument crashes
(:ticket:`29166`).
+
+* Fixed crash when using a ``Window()`` expression in a subquery
+ (:ticket:`29172`).
diff --git a/tests/expressions_window/tests.py b/tests/expressions_window/tests.py
index e61516b4b6..7ade53f429 100644
--- a/tests/expressions_window/tests.py
+++ b/tests/expressions_window/tests.py
@@ -650,6 +650,19 @@ class WindowFunctionTests(TestCase):
salary=Window(expression=Sum(Value(10000), order_by=F('pk').asc())),
)
+ def test_window_expression_within_subquery(self):
+ subquery_qs = Employee.objects.annotate(
+ highest=Window(FirstValue('id'), partition_by=F('department'), order_by=F('salary').desc())
+ ).values('highest')
+ highest_salary = Employee.objects.filter(pk__in=subquery_qs)
+ self.assertSequenceEqual(highest_salary.values('department', 'salary'), [
+ {'department': 'Accounting', 'salary': 50000},
+ {'department': 'Sales', 'salary': 55000},
+ {'department': 'Marketing', 'salary': 40000},
+ {'department': 'IT', 'salary': 60000},
+ {'department': 'Management', 'salary': 100000}
+ ])
+
def test_invalid_start_value_range(self):
msg = "start argument must be a negative integer, zero, or None, but got '3'."
with self.assertRaisesMessage(ValueError, msg):