#36030: Expressions that divide an integer field by a constant decimal.Decimal
returns inconsistent decimal places on SQLite
-------------------------------------+-------------------------------------
     Reporter:  Bartłomiej Nowak     |                    Owner:  Gregory
                                     |  Mariani
         Type:  Bug                  |                   Status:  assigned
    Component:  Database layer       |                  Version:  dev
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  division             |             Triage Stage:  Accepted
  decimalfield                       |
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

 * needs_docs:  1 => 0
 * summary:
     Expressions that divide an integer field by a constant decimal.Decimal
     returns inconsistent decimal places on PostgreSQL
     =>
     Expressions that divide an integer field by a constant decimal.Decimal
     returns inconsistent decimal places on SQLite

Comment:

 Some notes on the original report

 Using `Decimal(3.0)` (or `Decimal(float_var)`) means you lose control over
 the number of digits of precision:

 [https://docs.python.org/3/library/decimal.html#decimal.Decimal python
 docs]:
 > If value is a float, the binary floating-point value is losslessly
 converted to its exact decimal equivalent. This conversion can often
 require 53 or more digits of precision. For example, Decimal(float('1.1'))
 converts to
 Decimal('1.100000000000000088817841970012523233890533447265625').

 `Decimal(3.0)` requires no digits of precision:
 {{{#!py
 >>> Decimal(3.0)
 Decimal('3')
 }}}

 Results are consistent if you provide a string to the constructor, e.g
 `Decimal("3.0")`.
 ----
 Sarah did reframe the issue when accepting (and retitled the issue to
 match) in comment:7. I think we can continue in the same ticket: I posted
 a solution on the PR that focuses on the SQLite discrepancy:

 {{{#!diff
 diff --git a/django/db/models/expressions.py
 b/django/db/models/expressions.py
 index 0d47366d2c..00c0b751a2 100644
 --- a/django/db/models/expressions.py
 +++ b/django/db/models/expressions.py
 @@ -27,11 +27,12 @@ class SQLiteNumericMixin:

      def as_sqlite(self, compiler, connection, **extra_context):
          sql, params = self.as_sql(compiler, connection, **extra_context)
 -        try:
 -            if self.output_field.get_internal_type() == "DecimalField":
 -                sql = "(CAST(%s AS NUMERIC))" % sql
 -        except FieldError:
 -            pass
 +        if not(isinstance(self, Value) and isinstance(self.value,
 Decimal)):
 +            try:
 +                if self.output_field.get_internal_type() ==
 "DecimalField":
 +                    sql = "(CAST(%s AS NUMERIC))" % sql
 +            except FieldError:
 +                pass
          return sql, params
  }}}

 Please unset "patch needs improvement" when ready for a review.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36030#comment:18>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/0107019a9d811541-68e82bcd-c1b2-4ef1-9a9b-5fd8b4eee1f7-000000%40eu-central-1.amazonses.com.

Reply via email to