Opened 3 years ago

Closed 3 years ago

#33262 closed Bug (fixed)

Aggregate filtered by an Exists subquery crashes

Reported by: Hannes Ljungberg Owned by: Hannes Ljungberg
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

For example:

Book.objects.values("publisher").aggregate(
    max_rating=Max(
        "rating",
        filter=Exists(
            Book.authors.through.objects.filter(book=OuterRef("pk")),
        ),
    )

Will crash with the following traceback:

Traceback (most recent call last):
  File "/tests/django/tests/aggregation/test_filter_argument.py", line 146, in test_filtered_aggregate_with_exists
    aggregate = Book.objects.values('publisher').aggregate(
  File "/tests/django/django/db/models/query.py", line 405, in aggregate
    return query.get_aggregation(self.db, kwargs)
  File "/tests/django/django/db/models/sql/query.py", line 501, in get_aggregation
    result = compiler.execute_sql(SINGLE)
  File "/tests/django/django/db/models/sql/compiler.py", line 1189, in execute_sql
    sql, params = self.as_sql()
  File "/tests/django/django/db/models/sql/compiler.py", line 531, in as_sql
    extra_select, order_by, group_by = self.pre_sql_setup()
  File "/tests/django/django/db/models/sql/compiler.py", line 59, in pre_sql_setup
    self.setup_query()
  File "/tests/django/django/db/models/sql/compiler.py", line 50, in setup_query
    self.select, self.klass_info, self.annotation_col_map = self.get_select()
  File "/tests/django/django/db/models/sql/compiler.py", line 267, in get_select
    sql, params = self.compile(col)
  File "/tests/django/django/db/models/sql/compiler.py", line 463, in compile
    sql, params = node.as_sql(self, self.connection)
  File "/tests/django/django/db/models/aggregates.py", line 90, in as_sql
    return sql, params + filter_params
TypeError: can only concatenate list (not "tuple") to list

The following patch should fix the issue:

diff --git a/django/db/models/aggregates.py b/django/db/models/aggregates.py
index 596a161669..8c4eae7906 100644
--- a/django/db/models/aggregates.py
+++ b/django/db/models/aggregates.py
@@ -87,7 +87,7 @@ class Aggregate(Func):
                     compiler, connection, template=template, filter=filter_sql,
                     **extra_context
                 )
-                return sql, params + filter_params
+                return sql, (*params, *filter_params)
             else:
                 copy = self.copy()
                 copy.filter = None

Change History (4)

comment:1 by Hannes Ljungberg, 3 years ago

Has patch: set

comment:2 by Carlton Gibson, 3 years ago

Triage Stage: UnreviewedAccepted

comment:3 by Mariusz Felisiak, 3 years ago

Triage Stage: AcceptedReady for checkin

comment:4 by Mariusz Felisiak <felisiak.mariusz@…>, 3 years ago

Resolution: fixed
Status: assignedclosed

In a934d377:

Fixed #33262 -- Fixed crash of conditional aggregation on Exists().

Note: See TracTickets for help on using tickets.
Back to Top