Skip to content

Commit 69ff2e6

Browse files
committed
BUG19500097: Fix regression caused by C Extension
BUG#19500097 resurfaced with the merging of C Extension with the develop branch. We fix the regression and also fix the same problem of 'binary' character set in C Extension. The patch also fixes 'foreach_cnx' decorator in the tests, which was consuming all the Exceptions not allowing any test case failure to show up. We also fix set_charset_collation() method which was not setting the character set of the current connection properly. Unit tests are updated.
1 parent a4ba69f commit 69ff2e6

File tree

6 files changed

+51
-25
lines changed

6 files changed

+51
-25
lines changed

lib/mysql/connector/abstracts.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ def python_charset(self):
613613
Returns a string.
614614
"""
615615
encoding = CharacterSet.get_info(self._charset_id)[0]
616-
if encoding == 'utf8mb4':
616+
if encoding in ('utf8mb4', 'binary'):
617617
return 'utf8'
618618
else:
619619
return encoding
@@ -652,6 +652,14 @@ def set_charset_collation(self, charset=None, collation=None):
652652

653653
self._execute_query("SET NAMES '{0}' COLLATE '{1}'".format(
654654
charset_name, collation_name))
655+
656+
try:
657+
# Required for C Extension
658+
self.set_character_set_name(charset_name)
659+
except AttributeError:
660+
# Not required for pure Python connection
661+
pass
662+
655663
if self.converter:
656664
self.converter.set_charset(charset_name)
657665

lib/mysql/connector/connection_cext.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ def ping(self, reconnect=False, attempts=1, delay=0):
215215
else:
216216
raise errors.InterfaceError(errmsg)
217217

218+
def set_character_set_name(self, charset):
219+
"""Sets the default character set name for current connection.
220+
"""
221+
self._cmysql.set_character_set(charset)
222+
218223
def info_query(self, query):
219224
"""Send a query which only returns 1 row"""
220225
self._cmysql.query(query)

src/mysql_capi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,10 @@ MySQL_escape_string(MySQL *self, PyObject *value)
11781178

11791179
if (PyUnicode_Check(value))
11801180
{
1181+
if (strcmp(charset, "binary") == 0)
1182+
{
1183+
charset = "utf8";
1184+
}
11811185
from= PyUnicode_AsEncodedString(value, charset, NULL);
11821186
if (!from)
11831187
{

src/mysql_capi_conversion.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ mytopy_string(const char *data, const unsigned long length,
736736
const unsigned long flags, const char *charset,
737737
unsigned int use_unicode)
738738
{
739-
if (!(flags & BINARY_FLAG) && use_unicode)
739+
if (!(flags & BINARY_FLAG) && use_unicode && strcmp(charset, "binary") != 0)
740740
{
741741
return PyUnicode_Decode(data, length, charset, NULL);
742742
}

tests/__init__.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -430,18 +430,21 @@ def wrapper(self, *args, **kwargs):
430430
self.cnx = cnx_class(**self.config)
431431
self._testMethodName = "{0} (using {1})".format(
432432
func.__name__, cnx_class.__name__)
433-
func(self, *args, **kwargs)
434433
except:
435434
if hasattr(self, 'cnx'):
436435
# We will rollback/close later
437436
pass
438-
439437
try:
440-
self.cnx.rollback()
441-
self.cnx.close()
442-
except:
443-
# Might already be closed.
444-
pass
438+
func(self, *args, **kwargs)
439+
except Exception as exc:
440+
raise exc
441+
finally:
442+
try:
443+
self.cnx.rollback()
444+
self.cnx.close()
445+
except:
446+
# Might already be closed.
447+
pass
445448
return wrapper
446449
return _use_cnx
447450

tests/test_bugs.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3149,32 +3149,39 @@ class BugOra19500097(tests.MySQLConnectorTests):
31493149
"""
31503150
def setUp(self):
31513151
config = tests.get_mysql_config()
3152-
self.cnx = connection.MySQLConnection(**config)
3153-
self.cur = self.cnx.cursor()
3152+
cnx = connection.MySQLConnection(**config)
3153+
cur = cnx.cursor()
31543154

31553155
self.tbl = 'Bug19500097'
3156-
self.cur.execute("DROP TABLE IF EXISTS {0}".format(self.tbl))
3156+
cur.execute("DROP TABLE IF EXISTS {0}".format(self.tbl))
31573157

31583158
create = ("CREATE TABLE {0} (col1 VARCHAR(10), col2 INT) "
31593159
"DEFAULT CHARSET latin1".format(self.tbl))
3160-
self.cur.execute(create)
3160+
cur.execute(create)
3161+
cur.close()
3162+
cnx.close()
31613163

31623164
def tearDown(self):
3163-
self.cur.execute("DROP TABLE IF EXISTS {0}".format(self.tbl))
3164-
self.cur.close()
3165-
self.cnx.close()
3165+
config = tests.get_mysql_config()
3166+
cnx = connection.MySQLConnection(**config)
3167+
cur = cnx.cursor()
3168+
cur.execute("DROP TABLE IF EXISTS {0}".format(self.tbl))
3169+
cur.close()
3170+
cnx.close()
31663171

3172+
@foreach_cnx()
31673173
def test_binary_charset(self):
31683174

31693175
sql = "INSERT INTO {0} VALUES(%s, %s)".format(self.tbl)
3170-
self.cur.execute(sql, ('foo', 1))
3171-
self.cur.execute(sql, ('ëëë', 2))
3172-
self.cur.execute(sql, (u'ááá', 5))
3176+
cur = self.cnx.cursor()
3177+
cur.execute(sql, ('foo', 1))
3178+
cur.execute(sql, ('ëëë', 2))
3179+
cur.execute(sql, (u'ááá', 5))
31733180

31743181
self.cnx.set_charset_collation('binary')
3175-
self.cur.execute(sql, ('bar', 3))
3176-
self.cur.execute(sql, ('ëëë', 4))
3177-
self.cur.execute(sql, (u'ááá', 6))
3182+
cur.execute(sql, ('bar', 3))
3183+
cur.execute(sql, ('ëëë', 4))
3184+
cur.execute(sql, (u'ááá', 6))
31783185

31793186
exp = [
31803187
(bytearray(b'foo'), 1),
@@ -3184,9 +3191,8 @@ def test_binary_charset(self):
31843191
(bytearray(b'\xc3\xab\xc3\xab\xc3\xab'), 4),
31853192
(bytearray(b'\xc3\xa1\xc3\xa1\xc3\xa1'), 6)
31863193
]
3187-
3188-
self.cur.execute("SELECT * FROM {0}".format(self.tbl))
3189-
self.assertEqual(exp, self.cur.fetchall())
3194+
cur.execute("SELECT * FROM {0}".format(self.tbl))
3195+
self.assertEqual(exp, cur.fetchall())
31903196

31913197

31923198
@unittest.skipIf(tests.MYSQL_VERSION < (5, 7, 3),

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy