Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #16809 -- Forced MySQL to behave like a database. This avoids a…

… problem where queries that do IS NONE checks can return the wrong result the first time they are executed if there is a recently inserted row. Thanks to James Pyrich for the debug work and patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16785 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit fcee0c1b66019a0e84bc338e76fa31695d5bd4ca 1 parent 161c632
Russell Keith-Magee authored September 10, 2011
12  django/db/backends/mysql/base.py
@@ -309,7 +309,9 @@ def _valid_connection(self):
309 309
         return False
310 310
 
311 311
     def _cursor(self):
  312
+        new_connection = False
312 313
         if not self._valid_connection():
  314
+            new_connection = True
313 315
             kwargs = {
314 316
                 'conv': django_conversions,
315 317
                 'charset': 'utf8',
@@ -336,8 +338,14 @@ def _cursor(self):
336 338
             self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
337 339
             self.connection.encoders[SafeString] = self.connection.encoders[str]
338 340
             connection_created.send(sender=self.__class__, connection=self)
339  
-        cursor = CursorWrapper(self.connection.cursor())
340  
-        return cursor
  341
+        cursor = self.connection.cursor()
  342
+        if new_connection:
  343
+            # SQL_AUTO_IS_NULL in MySQL controls whether an AUTO_INCREMENT column
  344
+            # on a recently-inserted row will return when the field is tested for
  345
+            # NULL.  Disabling this value brings this aspect of MySQL in line with
  346
+            # SQL standards.
  347
+            cursor.execute('SET SQL_AUTO_IS_NULL = 0')
  348
+        return CursorWrapper(cursor)
341 349
 
342 350
     def _rollback(self):
343 351
         try:
13  tests/regressiontests/queries/tests.py
@@ -1070,10 +1070,6 @@ def test_ticket15316_exclude_false(self):
1070 1070
         ci3 = CategoryItem.objects.create(category=c3)
1071 1071
 
1072 1072
         qs = CategoryItem.objects.exclude(category__specialcategory__isnull=False)
1073  
-        # Under MySQL, this query gives incorrect values on the first attempt.
1074  
-        # If you run exactly the same query twice, it yields the right answer
1075  
-        # the second attempt. Oh, how we do love MySQL.
1076  
-        qs.count()
1077 1073
         self.assertEqual(qs.count(), 1)
1078 1074
         self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
1079 1075
 
@@ -1136,10 +1132,6 @@ def test_ticket15316_one2one_exclude_false(self):
1136 1132
         ci3 = CategoryItem.objects.create(category=c1)
1137 1133
 
1138 1134
         qs = CategoryItem.objects.exclude(category__onetoonecategory__isnull=False)
1139  
-        # Under MySQL, this query gives incorrect values on the first attempt.
1140  
-        # If you run exactly the same query twice, it yields the right answer
1141  
-        # the second attempt. Oh, how we do love MySQL.
1142  
-        qs.count()
1143 1135
         self.assertEqual(qs.count(), 1)
1144 1136
         self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
1145 1137
 
@@ -1421,11 +1413,6 @@ def test_tickets_8921_9188(self):
1421 1413
             []
1422 1414
         )
1423 1415
 
1424  
-        # This next makes exactly *zero* sense, but it works. It's needed
1425  
-        # because MySQL fails to give the right results the first time this
1426  
-        # query is executed. If you run the same query a second time, it
1427  
-        # works fine. It's a hack, but it works...
1428  
-        list(Tag.objects.exclude(children=None))
1429 1416
         self.assertQuerysetEqual(
1430 1417
             Tag.objects.exclude(children=None),
1431 1418
             ['<Tag: t1>', '<Tag: t3>']

0 notes on commit fcee0c1

Please sign in to comment.
Something went wrong with that request. Please try again.