Opened 3 hours ago
#36031 new Bug
DecimalRangeField __contains query for a value causes DataError
Reported by: | Trent Holliday | Owned by: | |
---|---|---|---|
Component: | contrib.postgres | Version: | 4.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
With a model of:
class Thing(models.Model): decimal_range = DecimalRangeField()
Attempting to query against the decimal range field using a value instead of a range of values leads to the below error being raised.
>>> list(Thing.objects.filter(decimal_range__contains=199)) Traceback (most recent call last): File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 89, in _execute return self.cursor.execute(sql, params) psycopg2.errors.InvalidTextRepresentation: invalid input syntax for type integer: "none" LINE 1: ...HERE "contractor_thing"."decimal_range" @> (199)::numeric(No... ^ The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/opt/homebrew/Cellar/python@3.10/3.10.14_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/code.py", line 90, in runcode exec(code, self.locals) File "<console>", line 1, in <module> File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/models/query.py", line 398, in __iter__ self._fetch_all() File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/models/query.py", line 1881, in _fetch_all self._result_cache = list(self._iterable_class(self)) File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/models/query.py", line 91, in __iter__ results = compiler.execute_sql( File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1562, in execute_sql cursor.execute(sql, params) File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 102, in execute return super().execute(sql, params) File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/cachalot/monkey_patch.py", line 137, in inner return original(cursor, sql, *args, **kwargs) File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/sentry_sdk/integrations/django/__init__.py", line 644, in execute result = real_execute(self, sql, params) File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 67, in execute return self._execute_with_wrappers( File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers return executor(sql, params, many, context) File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 84, in _execute with self.db.wrap_database_errors: File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/utils.py", line 91, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value File "/Users/tholliday/code/ADMS/backend/.venv/lib/python3.10/site-packages/django/db/backends/utils.py", line 89, in _execute return self.cursor.execute(sql, params) django.db.utils.DataError: invalid input syntax for type integer: "none" LINE 1: ...HERE "contractor_thing"."decimal_range" @> (199)::numeric(No...
I've done some digging to try and identify why this is happening. From what I can tell, when the DecimalRangeField
gets intialized, self.base_field
is a DecimalField
and gets instantiated with decimal_places
and max_digits
set to None, https://github.com/django/django/blame/fcd9d08379a2aee3b2c49eab0d0b8db6fd66d091/django/contrib/postgres/fields/ranges.py#L65. Then when the Cast
operation happens for the RangeContains
lookup here: https://github.com/django/django/blame/fcd9d08379a2aee3b2c49eab0d0b8db6fd66d091/django/contrib/postgres/fields/ranges.py#L215 it results in passing in the None values for the precision and scale.