Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #19954 -- Fixed MySQL _last_executed decoding

Queries can contain binary data undecodable with utf-8. In this
case, using the 'replace' errors mode when decoding seems like
an acceptable representation of the query.
Thanks Marcel Ryser for the report.
  • Loading branch information...
commit 86b1c316899f154b1800ab936330ac8924251e40 1 parent ef348b5
@claudep claudep authored
View
4 django/db/backends/mysql/base.py
@@ -37,7 +37,7 @@
from django.db.backends.mysql.creation import DatabaseCreation
from django.db.backends.mysql.introspection import DatabaseIntrospection
from django.db.backends.mysql.validation import DatabaseValidation
-from django.utils.encoding import force_str
+from django.utils.encoding import force_str, force_text
from django.utils.safestring import SafeBytes, SafeText
from django.utils import six
from django.utils import timezone
@@ -270,7 +270,7 @@ def last_executed_query(self, cursor, sql, params):
# With MySQLdb, cursor objects have an (undocumented) "_last_executed"
# attribute where the exact query sent to the database is saved.
# See MySQLdb/cursors.py in the source distribution.
- return cursor._last_executed.decode('utf-8')
+ return force_text(cursor._last_executed, errors='replace')
def no_limit_value(self):
# 2**64 - 1, as recommended by the MySQL documentation
View
1  tests/backends/models.py
@@ -62,6 +62,7 @@ class Meta:
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
+ raw_data = models.BinaryField()
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
View
10 tests/backends/tests.py
@@ -157,18 +157,18 @@ def test_django_date_extract(self):
class LastExecutedQueryTest(TestCase):
def test_debug_sql(self):
- list(models.Tag.objects.filter(name="test"))
+ list(models.Reporter.objects.filter(first_name="test"))
sql = connection.queries[-1]['sql'].lower()
self.assertIn("select", sql)
- self.assertIn(models.Tag._meta.db_table, sql)
+ self.assertIn(models.Reporter._meta.db_table, sql)
def test_query_encoding(self):
"""
Test that last_executed_query() returns an Unicode string
"""
- tags = models.Tag.objects.extra(select={'föö': 1})
- sql, params = tags.query.sql_with_params()
- cursor = tags.query.get_compiler('default').execute_sql(None)
+ persons = models.Reporter.objects.filter(raw_data=b'\x00\x46 \xFE').extra(select={'föö': 1})
+ sql, params = persons.query.sql_with_params()
+ cursor = persons.query.get_compiler('default').execute_sql(None)
last_sql = cursor.db.ops.last_executed_query(cursor, sql, params)
self.assertTrue(isinstance(last_sql, six.text_type))
Please sign in to comment.
Something went wrong with that request. Please try again.