From f2e2a1bd4be8ec7624b081488292b804777a526a Mon Sep 17 00:00:00 2001
From: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Date: Mon, 15 Oct 2018 15:57:22 +0200
Subject: [PATCH] Fixed #29845 -- Fixed Cast crash on MySQL when casting to
 DecimalField.

---
 django/db/backends/mysql/operations.py     |  1 +
 tests/db_functions/comparison/test_cast.py | 16 +++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py
index 07b5e85ba0..1414520eff 100644
--- a/django/db/backends/mysql/operations.py
+++ b/django/db/backends/mysql/operations.py
@@ -19,6 +19,7 @@ class DatabaseOperations(BaseDatabaseOperations):
         'AutoField': 'signed integer',
         'BigAutoField': 'signed integer',
         'CharField': 'char(%(max_length)s)',
+        'DecimalField': 'decimal(%(max_digits)s, %(decimal_places)s)',
         'TextField': 'char',
         'IntegerField': 'signed integer',
         'BigIntegerField': 'signed integer',
diff --git a/tests/db_functions/comparison/test_cast.py b/tests/db_functions/comparison/test_cast.py
index dafe0fa9aa..c5698d6d0e 100644
--- a/tests/db_functions/comparison/test_cast.py
+++ b/tests/db_functions/comparison/test_cast.py
@@ -10,7 +10,7 @@ from django.test import (
     TestCase, ignore_warnings, override_settings, skipUnlessDBFeature,
 )
 
-from ..models import Author, DTModel, Fan
+from ..models import Author, DTModel, Fan, FloatModel
 
 
 class CastTests(TestCase):
@@ -37,6 +37,20 @@ class CastTests(TestCase):
         names = Author.objects.annotate(cast_string=Cast('name', models.CharField(max_length=1)))
         self.assertEqual(names.get().cast_string, 'B')
 
+    @skipUnlessDBFeature('supports_cast_with_precision')
+    def test_cast_to_decimal_field(self):
+        FloatModel.objects.create(f1=-1.934, f2=3.467)
+        float_obj = FloatModel.objects.annotate(
+            cast_f1_decimal=Cast('f1', models.DecimalField(max_digits=8, decimal_places=2)),
+            cast_f2_decimal=Cast('f2', models.DecimalField(max_digits=8, decimal_places=1)),
+        ).get()
+        self.assertEqual(float_obj.cast_f1_decimal, decimal.Decimal('-1.93'))
+        self.assertEqual(float_obj.cast_f2_decimal, decimal.Decimal('3.5'))
+        author_obj = Author.objects.annotate(
+            cast_alias_decimal=Cast('alias', models.DecimalField(max_digits=8, decimal_places=2)),
+        ).get()
+        self.assertEqual(author_obj.cast_alias_decimal, decimal.Decimal('1'))
+
     def test_cast_to_integer(self):
         for field_class in (
             models.AutoField,