Skip to content

Commit 740912f

Browse files
peeyushguptaGeert Vanderkelen
authored and
Geert Vanderkelen
committed
BUG19549363: Raise error when compression used with reset_session
Change user command raises packets out of order error when used with compression. This causes error when a pooled connection tries to reset session which internally sends change user command for MySQL server 5.7.2 or earlier. We fix this by raising a NotSupportedError whenever someone tries to reset a session on MySQL server earlier than 5.7.3. A test case has been added for BUG#19549363. (cherry picked from commit 1b412b7)
1 parent fae86c0 commit 740912f

File tree

3 files changed

+91
-2
lines changed

3 files changed

+91
-2
lines changed

lib/mysql/connector/connection.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ def __init__(self, *args, **kwargs):
123123
self._ssl_active = False
124124
self._auth_plugin = None
125125
self._pool_config_version = None
126+
self._compress = False
126127

127128
if len(kwargs) > 0:
128129
self.connect(**kwargs)
@@ -271,6 +272,7 @@ def config(self, **kwargs):
271272

272273
try:
273274
if config['compress']:
275+
self._compress = True
274276
self.set_client_flags([ClientFlag.COMPRESS])
275277
except KeyError:
276278
pass # Missing compress argument is OK
@@ -884,6 +886,10 @@ def cmd_change_user(self, username='', password='', database='',
884886
if self.unread_result:
885887
raise errors.InternalError("Unread result found.")
886888

889+
if self._compress:
890+
raise errors.NotSupportedError("Change user is not supported with "
891+
"compression.")
892+
887893
packet = self._protocol.make_change_user(
888894
handshake=self._handshake,
889895
username=username, password=password, database=database,
@@ -943,8 +949,13 @@ def reset_session(self, user_variables=None, session_variables=None):
943949
try:
944950
self.cmd_reset_connection()
945951
except errors.NotSupportedError:
946-
self.cmd_change_user(self._user, self._password,
947-
self._database, self._charset_id)
952+
if self._compress:
953+
raise errors.NotSupportedError(
954+
"Reset session is not supported with compression for "
955+
"MySQL server version 5.7.2 or earlier.")
956+
else:
957+
self.cmd_change_user(self._user, self._password,
958+
self._database, self._charset_id)
948959

949960
cur = self.cursor()
950961
if user_variables:

lib/mysql/connector/pooling.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,17 @@ def add_connection(self, cnx=None):
269269

270270
if not cnx:
271271
cnx = MySQLConnection(**self._cnx_config)
272+
try:
273+
if (self._reset_session and self._cnx_config['compress']
274+
and cnx.get_server_version() < (5, 7, 3)):
275+
raise errors.NotSupportedError("Pool reset session is "
276+
"not supported with "
277+
"compression for MySQL "
278+
"server version 5.7.2 "
279+
"or earlier.")
280+
except KeyError:
281+
pass
282+
272283
# pylint: disable=W0201,W0212
273284
cnx._pool_config_version = self._config_version
274285
# pylint: enable=W0201,W0212

tests/test_bugs.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,3 +2960,70 @@ def test_row_to_python(self):
29602960
cur.execute("INSERT INTO {0} (c1) VALUES (?)".format(self.tbl), (data,))
29612961
self.cur.execute("SELECT * FROM {0}".format(self.tbl))
29622962
self.assertEqual((data,), self.cur.fetchone())
2963+
2964+
2965+
class BugOra19500097(tests.MySQLConnectorTests):
2966+
"""BUG#19500097: BETTER SUPPORT FOR RAW/BINARY DATA
2967+
"""
2968+
def setUp(self):
2969+
config = tests.get_mysql_config()
2970+
self.cnx = connection.MySQLConnection(**config)
2971+
self.cur = self.cnx.cursor()
2972+
2973+
self.tbl = 'Bug19500097'
2974+
self.cur.execute("DROP TABLE IF EXISTS {0}".format(self.tbl))
2975+
2976+
create = ("CREATE TABLE {0} (col1 VARCHAR(10), col2 INT) "
2977+
"DEFAULT CHARSET latin1".format(self.tbl))
2978+
self.cur.execute(create)
2979+
2980+
def tearDown(self):
2981+
self.cur.execute("DROP TABLE IF EXISTS {0}".format(self.tbl))
2982+
self.cur.close()
2983+
self.cnx.close()
2984+
2985+
def test_binary_charset(self):
2986+
2987+
sql = "INSERT INTO {0} VALUES(%s, %s)".format(self.tbl)
2988+
self.cur.execute(sql, ('foo', 1))
2989+
self.cur.execute(sql, ('ëëë', 2))
2990+
self.cur.execute(sql, (u'ááá', 5))
2991+
2992+
self.cnx.set_charset_collation('binary')
2993+
self.cur.execute(sql, ('bar', 3))
2994+
self.cur.execute(sql, ('ëëë', 4))
2995+
self.cur.execute(sql, (u'ááá', 6))
2996+
2997+
exp = [
2998+
(bytearray(b'foo'), 1),
2999+
(bytearray(b'\xeb\xeb\xeb'), 2),
3000+
(bytearray(b'\xe1\xe1\xe1'), 5),
3001+
(bytearray(b'bar'), 3),
3002+
(bytearray(b'\xc3\xab\xc3\xab\xc3\xab'), 4),
3003+
(bytearray(b'\xc3\xa1\xc3\xa1\xc3\xa1'), 6)
3004+
]
3005+
3006+
self.cur.execute("SELECT * FROM {0}".format(self.tbl))
3007+
self.assertEqual(exp, self.cur.fetchall())
3008+
3009+
3010+
@unittest.skipIf(tests.MYSQL_VERSION < (5, 7, 3),
3011+
"MySQL {0} does not support COM_RESET_CONNECTION".format(
3012+
tests.MYSQL_VERSION_TXT))
3013+
class BugOra19549363(tests.MySQLConnectorTests):
3014+
"""BUG#19549363: Compression does not work with Change User
3015+
"""
3016+
def test_compress(self):
3017+
config = tests.get_mysql_config()
3018+
config['compress'] = True
3019+
3020+
mysql.connector._CONNECTION_POOLS = {}
3021+
config['pool_name'] = 'mypool'
3022+
config['pool_size'] = 3
3023+
config['pool_reset_session'] = True
3024+
cnx1 = mysql.connector.connect(**config)
3025+
3026+
try:
3027+
cnx1.close()
3028+
except:
3029+
self.fail("Reset session with compression test failed.")

0 commit comments

Comments
 (0)