#33282: django.db.utils.ProgrammingError: more than one row returned by a 
subquery
used as an expression
-------------------------------------+-------------------------------------
     Reporter:  Antonio Terceiro     |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  3.2
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  1                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

 * stage:  Unreviewed => Accepted


Comment:

 Managed to reproduce with this tests

 {{{#!diff
 diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py
 index 9ba70cb35e..f3277d2b5f 100644
 --- a/tests/aggregation/tests.py
 +++ b/tests/aggregation/tests.py
 @@ -1335,6 +1335,14 @@ def
 test_aggregation_nested_subquery_outerref(self):
          ).values_list('publisher_count', flat=True)
          self.assertSequenceEqual(books_breakdown, [1] * 6)

 +    def test_filter_in_subquery_or_aggregation(self):
 +        authors = Author.objects.annotate(
 +            books_count=Count('book'),
 +        ).filter(
 +            Q(pk__in=Book.objects.values('authors')) |
 Q(books_count__gt=0)
 +        )
 +        self.assertQuerysetEqual(authors, Author.objects.all(),
 ordered=False)
 +
      def test_aggregation_random_ordering(self):
          """Random() is not included in the GROUP BY when used for
 ordering."""
          authors =
 Author.objects.annotate(contact_count=Count('book')).order_by('?')
 }}}

 The gist of it is that the logic that was added to
 `Subquery.get_group_by_cols` should have been added to
 `sql.Query.get_group_by_cols` and the latter should have proxied it.

 The issue is triggered when a lookup containing a subquery is combined
 using `OR` to a lookup against an aggregation. When this happens the ORM
 has to choice but to push the filtering to the `HAVING` clause and thus
 group by all inputs passed down to the lookups. Since `Subquery` resolves
 to `sql.Query` and the latter defaults to returning `self` as inherited
 from `BaseExpression` the ORM tries to group by a subquery that
 potentially returns multiple rows.

 Antonio if don't mind if I assign the issue to me I have a patch set
 almost ready to address the problem and include extra regression tests for
 new uses cases such as lookup annotations which is a newly supported in
 4.0.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33282#comment:8>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.2e6be61892e03aad5bbf2ca9671e4759%40djangoproject.com.

Reply via email to