#35833: Annotation yielding an empty set causes entire QuerySet to become empty
-------------------------------------+-------------------------------------
     Reporter:  Jacob Walls          |                     Type:  Bug
       Status:  new                  |                Component:  Database
                                     |  layer (models, ORM)
      Version:  5.1                  |                 Severity:  Normal
     Keywords:                       |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
 With a nullable JSONField in my model:

 {{{
 class TileModel(models.Model):
    provisionaledits = JSONField(null=True)
 }}}

 If I then annotate with a set-returning function (e.g.
 JSONB_ARRAY_ELEMENTS on postgres) that happens to return an empty set, the
 entire QuerySet is zeroed out.

 {{{
 In [1]: from django.db.models import Func, F

 In [2]: from arches.app.models.models import TileModel

 In [3]: class JsonbArrayElements(Func):
    ...:     arity = 1
    ...:     contains_subquery = True  # Django 5.2: set_returning = True
    ...:     function = "JSONB_ARRAY_ELEMENTS"
    ...:

 In [4]: TileModel.objects.count()
 Out[4]: 9

 In [5]:
 TileModel.objects.annotate(empty_set=JsonbArrayElements(F("provisionaledits")))
 Out[5]: <QuerySet []>
 }}}

 I distilled this from a more complicated failure. If it helps, here is a
 query that fails more helpfully when you actually have JSON in the queried
 field but still can't extract array elements because it's not an array:

 {{{
 In [14]: TileModel.objects.create(provisionaledits={})
 Out[14]: <TileModel: TileModel object
 (6ee450f7-b516-4c61-b6e7-52e876b878fe)>

 In [15]:
 
TileModel.objects.annotate(no_longer_empty=JsonbArrayElements(F("provisionaledits")))
 Out[15]: DataError: cannot extract elements from an object
 }}}

 I guess I would expect an error in both cases instead of an empty queryset
 in the former. At the very least, I would only expect the annotation to
 yield some sort of empty value, not for the whole queryset to silently
 become empty.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35833>
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/01070192825023c8-d5142eb9-737c-41c9-bc27-d57c1c3cec57-000000%40eu-central-1.amazonses.com.

Reply via email to