Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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
Claude Paroz authored March 28, 2013
4  django/db/backends/mysql/base.py
@@ -37,7 +37,7 @@
37 37
 from django.db.backends.mysql.creation import DatabaseCreation
38 38
 from django.db.backends.mysql.introspection import DatabaseIntrospection
39 39
 from django.db.backends.mysql.validation import DatabaseValidation
40  
-from django.utils.encoding import force_str
  40
+from django.utils.encoding import force_str, force_text
41 41
 from django.utils.safestring import SafeBytes, SafeText
42 42
 from django.utils import six
43 43
 from django.utils import timezone
@@ -270,7 +270,7 @@ def last_executed_query(self, cursor, sql, params):
270 270
         # With MySQLdb, cursor objects have an (undocumented) "_last_executed"
271 271
         # attribute where the exact query sent to the database is saved.
272 272
         # See MySQLdb/cursors.py in the source distribution.
273  
-        return cursor._last_executed.decode('utf-8')
  273
+        return force_text(cursor._last_executed, errors='replace')
274 274
 
275 275
     def no_limit_value(self):
276 276
         # 2**64 - 1, as recommended by the MySQL documentation
1  tests/backends/models.py
@@ -62,6 +62,7 @@ class Meta:
62 62
 class Reporter(models.Model):
63 63
     first_name = models.CharField(max_length=30)
64 64
     last_name = models.CharField(max_length=30)
  65
+    raw_data = models.BinaryField()
65 66
 
66 67
     def __str__(self):
67 68
         return "%s %s" % (self.first_name, self.last_name)
10  tests/backends/tests.py
@@ -157,18 +157,18 @@ def test_django_date_extract(self):
157 157
 class LastExecutedQueryTest(TestCase):
158 158
 
159 159
     def test_debug_sql(self):
160  
-        list(models.Tag.objects.filter(name="test"))
  160
+        list(models.Reporter.objects.filter(first_name="test"))
161 161
         sql = connection.queries[-1]['sql'].lower()
162 162
         self.assertIn("select", sql)
163  
-        self.assertIn(models.Tag._meta.db_table, sql)
  163
+        self.assertIn(models.Reporter._meta.db_table, sql)
164 164
 
165 165
     def test_query_encoding(self):
166 166
         """
167 167
         Test that last_executed_query() returns an Unicode string
168 168
         """
169  
-        tags = models.Tag.objects.extra(select={'föö': 1})
170  
-        sql, params = tags.query.sql_with_params()
171  
-        cursor = tags.query.get_compiler('default').execute_sql(None)
  169
+        persons = models.Reporter.objects.filter(raw_data=b'\x00\x46  \xFE').extra(select={'föö': 1})
  170
+        sql, params = persons.query.sql_with_params()
  171
+        cursor = persons.query.get_compiler('default').execute_sql(None)
172 172
         last_sql = cursor.db.ops.last_executed_query(cursor, sql, params)
173 173
         self.assertTrue(isinstance(last_sql, six.text_type))
174 174
 

0 notes on commit 86b1c31

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