Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#26219 closed Bug (fixed)

Cannot filter by DecimalField in RawQuery

Reported by: jirek Owned by: Akshesh Doshi
Component: Database layer (models, ORM) Version: 1.9
Severity: Release blocker Keywords: DecimalField RawQuery
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

class Product(models.Model):
    name = models.CharField(max_length=128)
    price = models.DecimalField(max_digits=15, decimal_places=2, default=0, blank=True)

products = Product.objects.raw(""" SELECT * FROM "products_product" WHERE price >= %s """, params=[Decimal(200), ])
for product in products:
    print product

this will raise following exception

File "site-packages\django\db\models\query.py", line 1219, in __iter__
    query = iter(self.query)
  File "site-packages\django\db\models\sql\query.py", line 79, in __iter__
    self._execute_query()
  File "site-packages\django\db\models\sql\query.py", line 106, in _execute_query
    params = tuple(adapter(val) for val in self.params)
  File "site-packages\django\db\models\sql\query.py", line 106, in <genexpr>
    params = tuple(adapter(val) for val in self.params)
  File "site-packages\django\db\backends\base\operations.py", line 455, in adapt_unknown_value
    return self.adapt_decimalfield_value(value)
TypeError: adapt_decimalfield_value() takes exactly 4 arguments (2 given)

We are making much more complex query, this is just simple example of bug we are challenging

Change History (8)

comment:1 by Josh Smeaton, 8 years ago

Triage Stage: UnreviewedAccepted

Yep, this is indeed a bug. The following patch seems to fix the problem, but I haven't run the test suite to verify no bad behaviour is introduced. This is probably a regression introduced in 1.8 (I think). I remember modifying this code around then.

diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py
index 7957265..10641bf 100644
--- a/django/db/backends/base/operations.py
+++ b/django/db/backends/base/operations.py
@@ -485,7 +485,7 @@ class BaseDatabaseOperations(object):
             raise ValueError("Django does not support timezone-aware times.")
         return six.text_type(value)

-    def adapt_decimalfield_value(self, value, max_digits, decimal_places):
+    def adapt_decimalfield_value(self, value, max_digits=None, decimal_places=None):
         """
         Transforms a decimal.Decimal value to an object compatible with what is
         expected by the backend driver for decimal (numeric) columns.

comment:2 by Simon Charette, 8 years ago

Has patch: set
Severity: NormalRelease blocker

Ahh we did a bit of concurrent research!

This is regression introduced by d9521f66b1851b0eacd55bc78f801dc64123e333 in 1.9+.

The proposed patch is what I also had in mind.

comment:3 by Tim Graham, 8 years ago

Needs tests: set

comment:4 by Simon Charette, 8 years ago

Easy pickings: set

Marking as easy picking since a test can easily be written from the report.

comment:5 by Akshesh Doshi, 8 years ago

Has patch: unset
Owner: changed from nobody to Akshesh Doshi
Status: newassigned

comment:7 by Tim Graham <timograham@…>, 8 years ago

Resolution: fixed
Status: assignedclosed

In fdccc025:

Fixed #26219 -- Fixed crash when filtering by Decimal in RawQuery.

comment:8 by Tim Graham <timograham@…>, 8 years ago

In 0d2b97ca:

[1.9.x] Fixed #26219 -- Fixed crash when filtering by Decimal in RawQuery.

Backport of fdccc02576ae5a524338f65e629948604d80b4c8 from master

Note: See TracTickets for help on using tickets.
Back to Top