Opened 14 months ago

Last modified 14 months ago

#34858 closed Bug

Bug in output field handling — at Version 2

Reported by: Toan Vuong Owned by: nobody
Component: Database layer (models, ORM) Version: 4.2
Severity: Normal Keywords:
Cc: Simon Charette, Luke Plant 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 (last modified by Toan Vuong)

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.

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...

Change History (2)

comment:1 by Toan Vuong, 14 months ago

Description: modified (diff)

comment:2 by Toan Vuong, 14 months ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top