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
This commit is contained in:
parent
161c6328a0
commit
fcee0c1b66
|
@ -309,7 +309,9 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _cursor(self):
|
def _cursor(self):
|
||||||
|
new_connection = False
|
||||||
if not self._valid_connection():
|
if not self._valid_connection():
|
||||||
|
new_connection = True
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'conv': django_conversions,
|
'conv': django_conversions,
|
||||||
'charset': 'utf8',
|
'charset': 'utf8',
|
||||||
|
@ -336,8 +338,14 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
|
self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
|
||||||
self.connection.encoders[SafeString] = self.connection.encoders[str]
|
self.connection.encoders[SafeString] = self.connection.encoders[str]
|
||||||
connection_created.send(sender=self.__class__, connection=self)
|
connection_created.send(sender=self.__class__, connection=self)
|
||||||
cursor = CursorWrapper(self.connection.cursor())
|
cursor = self.connection.cursor()
|
||||||
return 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):
|
def _rollback(self):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1070,10 +1070,6 @@ class Queries4Tests(BaseQuerysetTest):
|
||||||
ci3 = CategoryItem.objects.create(category=c3)
|
ci3 = CategoryItem.objects.create(category=c3)
|
||||||
|
|
||||||
qs = CategoryItem.objects.exclude(category__specialcategory__isnull=False)
|
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.assertEqual(qs.count(), 1)
|
||||||
self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
|
self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
|
||||||
|
|
||||||
|
@ -1136,10 +1132,6 @@ class Queries4Tests(BaseQuerysetTest):
|
||||||
ci3 = CategoryItem.objects.create(category=c1)
|
ci3 = CategoryItem.objects.create(category=c1)
|
||||||
|
|
||||||
qs = CategoryItem.objects.exclude(category__onetoonecategory__isnull=False)
|
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.assertEqual(qs.count(), 1)
|
||||||
self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
|
self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
|
||||||
|
|
||||||
|
@ -1421,11 +1413,6 @@ class Queries6Tests(TestCase):
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
# 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(
|
self.assertQuerysetEqual(
|
||||||
Tag.objects.exclude(children=None),
|
Tag.objects.exclude(children=None),
|
||||||
['<Tag: t1>', '<Tag: t3>']
|
['<Tag: t1>', '<Tag: t3>']
|
||||||
|
|
Loading…
Reference in New Issue