From dd82f3327124fd2762cf6df2ac8c6380772bf127 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Fri, 29 Sep 2017 14:50:51 -0400
Subject: [PATCH] Fixed #27979 -- Made MySQL raise IntegrityError rather than
 OperationalError when saving negative numbers in PositiveInteger fields.

---
 django/db/backends/mysql/base.py        |  5 ++++-
 tests/model_fields/test_integerfield.py | 11 ++++++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index 1eb3677b80..57ef2ad2a0 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -57,7 +57,10 @@ class CursorWrapper:
     Implemented as a wrapper, rather than a subclass, so that it isn't stuck
     to the particular underlying representation returned by Connection.cursor().
     """
-    codes_for_integrityerror = (1048,)
+    codes_for_integrityerror = (
+        1048,  # Column cannot be null
+        1690,  # BIGINT UNSIGNED value is out of range
+    )
 
     def __init__(self, cursor):
         self.cursor = cursor
diff --git a/tests/model_fields/test_integerfield.py b/tests/model_fields/test_integerfield.py
index 99d7b1797c..5c7ba47fbb 100644
--- a/tests/model_fields/test_integerfield.py
+++ b/tests/model_fields/test_integerfield.py
@@ -1,6 +1,8 @@
+import unittest
+
 from django.core import validators
 from django.core.exceptions import ValidationError
-from django.db import connection, models
+from django.db import IntegrityError, connection, models
 from django.test import SimpleTestCase, TestCase
 
 from .models import (
@@ -151,6 +153,13 @@ class PositiveIntegerFieldTests(IntegerFieldTests):
     model = PositiveIntegerModel
     documented_range = (0, 2147483647)
 
+    @unittest.skipIf(connection.vendor == 'sqlite', "SQLite doesn't have a constraint.")
+    def test_negative_values(self):
+        p = PositiveIntegerModel.objects.create(value=0)
+        p.value = models.F('value') - 1
+        with self.assertRaises(IntegrityError):
+            p.save()
+
 
 class ValidationTests(SimpleTestCase):