Author: russellm
Date: 2011-09-10 11:58:30 -0700 (Sat, 10 Sep 2011)
New Revision: 16785

Modified:
   django/trunk/django/db/backends/mysql/base.py
   django/trunk/tests/regressiontests/queries/tests.py
Log:
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.

Modified: django/trunk/django/db/backends/mysql/base.py
===================================================================
--- django/trunk/django/db/backends/mysql/base.py       2011-09-10 18:44:33 UTC 
(rev 16784)
+++ django/trunk/django/db/backends/mysql/base.py       2011-09-10 18:58:30 UTC 
(rev 16785)
@@ -309,7 +309,9 @@
         return False
 
     def _cursor(self):
+        new_connection = False
         if not self._valid_connection():
+            new_connection = True
             kwargs = {
                 'conv': django_conversions,
                 'charset': 'utf8',
@@ -336,8 +338,14 @@
             self.connection.encoders[SafeUnicode] = 
self.connection.encoders[unicode]
             self.connection.encoders[SafeString] = 
self.connection.encoders[str]
             connection_created.send(sender=self.__class__, connection=self)
-        cursor = CursorWrapper(self.connection.cursor())
-        return cursor
+        cursor = self.connection.cursor()
+        if new_connection:
+            # SQL_AUTO_IS_NULL in MySQL controls whether an AUTO_INCREMENT 
column
+            # on a recently-inserted row will return when the field is tested 
for
+            # NULL.  Disabling this value brings this aspect of MySQL in line 
with
+            # SQL standards.
+            cursor.execute('SET SQL_AUTO_IS_NULL = 0')
+        return CursorWrapper(cursor)
 
     def _rollback(self):
         try:

Modified: django/trunk/tests/regressiontests/queries/tests.py
===================================================================
--- django/trunk/tests/regressiontests/queries/tests.py 2011-09-10 18:44:33 UTC 
(rev 16784)
+++ django/trunk/tests/regressiontests/queries/tests.py 2011-09-10 18:58:30 UTC 
(rev 16785)
@@ -1070,10 +1070,6 @@
         ci3 = CategoryItem.objects.create(category=c3)
 
         qs = 
CategoryItem.objects.exclude(category__specialcategory__isnull=False)
-        # Under MySQL, this query gives incorrect values on the first attempt.
-        # If you run exactly the same query twice, it yields the right answer
-        # the second attempt. Oh, how we do love MySQL.
-        qs.count()
         self.assertEqual(qs.count(), 1)
         self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
 
@@ -1136,10 +1132,6 @@
         ci3 = CategoryItem.objects.create(category=c1)
 
         qs = 
CategoryItem.objects.exclude(category__onetoonecategory__isnull=False)
-        # Under MySQL, this query gives incorrect values on the first attempt.
-        # If you run exactly the same query twice, it yields the right answer
-        # the second attempt. Oh, how we do love MySQL.
-        qs.count()
         self.assertEqual(qs.count(), 1)
         self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
 
@@ -1421,11 +1413,6 @@
             []
         )
 
-        # This next makes exactly *zero* sense, but it works. It's needed
-        # because MySQL fails to give the right results the first time this
-        # query is executed. If you run the same query a second time, it
-        # works fine. It's a hack, but it works...
-        list(Tag.objects.exclude(children=None))
         self.assertQuerysetEqual(
             Tag.objects.exclude(children=None),
             ['<Tag: t1>', '<Tag: t3>']

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to