[Django] #34858: Bug in output field handling

28 views
Skip to first unread message

Django

unread,
Sep 20, 2023, 3:39:18 PM9/20/23
to django-...@googlegroups.com
#34858: Bug in output field handling
-----------------------------------------+------------------------
Reporter: Toan Vuong | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.2
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 |
-----------------------------------------+------------------------
Tested on Django 4.2.4.

My model is defined like this:

```
class Choice(models.Model):
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
arbitrary_num = models.PositiveIntegerField(default=1)
arbitrary_num2 = models.PositiveIntegerField(default=2)
```

And this query is failing with Oracle (Tested on 19.3), but not Postgres:

```
s = Coalesce(F('arbitrary_num') + F('arbitrary_num2'),
Value(0, PositiveIntegerField()))
case = Case(
When(arbitrary_num=1, then=Value(1, PositiveIntegerField())),
default=s,
output_field=PositiveIntegerField()
)

qs = Choice.objects.annotate(ss=case)
list(qs)

#qs = Choice.objects.annotate(s=s)
#list(qs)

```

The error (It's talking about the `Coalesce` function not having an
`output_field`):

```
django.core.exceptions.FieldError: Expression contains mixed types:
IntegerField, PositiveIntegerField. You must set output_field.
```

I believe the error is correct, because I think adding two
`PositiveIntegerField()` seem to result in an `IntegerField`, so we *need*
to specify an `output_field` on `Coalesce` to tell Django the proper
output type to use. My question is that this seem to only throw an error
in Oracle, and *not* Postgres. So it seems like the behavior on Postgres
is unexpected? Somehow, the `Case` statement swallows the exception in
Postgres and generates correct result. This can be demonstrated by the
queryset where the `Coalesce` function is annotated directly without a
case statement -- in this case, both Postgres and Oracle fails with the
above error.

Note that this used to work prior to 4.2 (we upgraded from 3.x, where this
used to work), although again I believe it was incorrect behavior and an
`output_field` *should* be specified.

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

Django

unread,
Sep 20, 2023, 3:39:59 PM9/20/23
to django-...@googlegroups.com
#34858: Bug in output field handling
-------------------------------+--------------------------------------

Reporter: Toan Vuong | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.2
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by Toan Vuong:

Old description:

New description:

Tested on Django 4.2.4.

qs = Choice.objects.annotate(ss=case)
list(qs)

#qs = Choice.objects.annotate(s=s)
#list(qs)
}}}

--

--
Ticket URL: <https://code.djangoproject.com/ticket/34858#comment:1>

Django

unread,
Sep 20, 2023, 4:28:12 PM9/20/23
to django-...@googlegroups.com

Old description:

New description:

Tested on Django 4.2.4.

qs = Choice.objects.annotate(ss=case)
list(qs)

#qs = Choice.objects.annotate(s=s)
#list(qs)
}}}


On the other hand, it's a little strange that adding two
`PositiveIntegerField()` results in an output type of `IntegerField()`, so
perhaps that's a bug as well...

--

--
Ticket URL: <https://code.djangoproject.com/ticket/34858#comment:2>

Reply all
Reply to author
Forward
0 new messages