#35257: db.models.expressions _connector_combinations for Numeric with NULL returns
only FloatField instead of (IntegerField, DecimalField, FloatField)
-------------------------------------+-------------------------------------
Reporter: Sharon | Owner: nobody
Woo |
Type: Bug | Status: assigned
Component: Database | Version: 5.0
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Discovered via writing tests for this related ticket with a LOT of help
from David Sanders --
https://code.djangoproject.com/ticket/35235.
In
https://github.com/django/django/blob/ef2434f8508551fee183079ab471b1dc325c7acb/django/db/models/expressions.py#L599-L613
via
https://github.com/django/django/pull/15271,
the dictionary comprehension below
{{{
{
connector: [
(field_type, NoneType, field_type),
(NoneType, field_type, field_type),
]
for connector in (
Combinable.ADD,
Combinable.SUB,
Combinable.MUL,
Combinable.DIV,
Combinable.MOD,
Combinable.POW,
)
for field_type in (fields.IntegerField, fields.DecimalField,
fields.FloatField)
},
}}}
returns
{{{
Combinable.ADD: [(fields.FloatField, NoneType, fields.FloatField),
(NoneType, fields.FloatField, fields.FloatField),],
Combinable.SUB: [(fields.FloatField, NoneType, fields.FloatField),
(NoneType, fields.FloatField, fields.FloatField),],
...
}}}
instead of the expected
{{{
Combinable.ADD: [(fields.IntegerField, NoneType, fields.IntegerField),
(NoneType, fields.IntegerField, fields.IntegerField),
(fields.DecimalField, NoneType, fields.DecimalField),
(NoneType, fields.DecimalField, fields.DecimalField),
(fields.FloatField, NoneType, fields.FloatField),
(NoneType, fields.FloatField, fields.FloatField),
],
...
}}}
This leads to only FloatField throwing FieldError with
`_output_field_or_none` when fields are combined with NULL.
Examples you can run right now:
{{{
original_dict_comp = {
connector: (
(field_type, None, field_type),
(None, field_type, field_type),
)
for connector in (
'ADD', 'SUB', 'MUL', 'DIV', 'MOD', 'POW',
)
for field_type in ('IntegerField', 'DecimalField', 'FloatField')
}
# there are a few ways to write this one
fixed_dict_comp = {
key: [
(field_type, None, field_type)
for field_type in ['IntegerField', 'DecimalField', 'FloatField']
] + [
(None, field_type, field_type)
for field_type in ['IntegerField', 'DecimalField', 'FloatField']
]
for key in ['ADD', 'SUB', 'MUL', 'DIV', 'MOD', 'POW']
}
}}}
--
Ticket URL: <
https://code.djangoproject.com/ticket/35257>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.