mirror of
https://github.com/django/django.git
synced 2026-02-09 02:49:25 +08:00
Fixed #36030 -- Fixed precision loss in division of Decimal literals on SQLite.
Thanks Bob Kline for the review.
This commit is contained in:
@@ -1141,7 +1141,7 @@ class Func(SQLiteNumericMixin, Expression):
|
||||
|
||||
|
||||
@deconstructible(path="django.db.models.Value")
|
||||
class Value(SQLiteNumericMixin, Expression):
|
||||
class Value(Expression):
|
||||
"""Represent a wrapped value as a node within an expression."""
|
||||
|
||||
# Provide a default value for `for_save` in order to allow unresolved
|
||||
@@ -1182,6 +1182,18 @@ class Value(SQLiteNumericMixin, Expression):
|
||||
return "NULL", []
|
||||
return "%s", [val]
|
||||
|
||||
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":
|
||||
if isinstance(self.value, Decimal):
|
||||
sql = "(CAST(%s AS REAL))" % sql
|
||||
else:
|
||||
sql = "(CAST(%s AS NUMERIC))" % sql
|
||||
except FieldError:
|
||||
pass
|
||||
return sql, params
|
||||
|
||||
def resolve_expression(
|
||||
self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False
|
||||
):
|
||||
|
||||
@@ -137,6 +137,16 @@ class BasicExpressionsTests(TestCase):
|
||||
)
|
||||
self.assertEqual(companies["result"], 2395)
|
||||
|
||||
def test_decimal_division_literal_value(self):
|
||||
"""
|
||||
Division with a literal Decimal value preserves precision.
|
||||
"""
|
||||
num = Number.objects.create(integer=2)
|
||||
obj = Number.objects.annotate(
|
||||
val=F("integer") / Value(Decimal("3.0"), output_field=DecimalField())
|
||||
).get(pk=num.pk)
|
||||
self.assertAlmostEqual(obj.val, Decimal("0.6667"), places=4)
|
||||
|
||||
def test_annotate_values_filter(self):
|
||||
companies = (
|
||||
Company.objects.annotate(
|
||||
|
||||
Reference in New Issue
Block a user