8000 Fix SELECT CAST(... AS JSON) cause UnicodeError · PyMySQL/PyMySQL@a568397 · GitHub
[go: up one dir, main page]

Skip to content

Commit a568397

Browse files
committed
Fix SELECT CAST(... AS JSON) cause UnicodeError
fixes #488
1 parent 666ff95 commit a568397

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

pymysql/charset.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ def __init__(self, id, name, collation, is_default):
1111
self.id, self.name, self.collation = id, name, collation
1212
self.is_default = is_default == 'Yes'
1313

14+
def __repr__(self):
15+
return "Charset(id=%s, name=%r, collation=%r)" % (
16+
self.id, self.name, self.collation)
17+
1418
@property
1519
def encoding(self):
1620
name = self.name

pymysql/connections.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ def _makefile(sock, mode):
8888
FIELD_TYPE.BLOB,
8989
FIELD_TYPE.LONG_BLOB,
9090
FIELD_TYPE.MEDIUM_BLOB,
91-
FIELD_TYPE.JSON,
9291
FIELD_TYPE.STRING,
9392
FIELD_TYPE.TINY_BLOB,
9493
FIELD_TYPE.VAR_STRING,
@@ -407,9 +406,9 @@ class FieldDescriptorPacket(MysqlPacket):
407406

408407
def __init__(self, data, encoding):
409408
MysqlPacket.__init__(self, data, encoding)
410-
self.__parse_field_descriptor(encoding)
409+
self._parse_field_descriptor(encoding)
411410

412-
def __parse_field_descriptor(self, encoding):
411+
def _parse_field_descriptor(self, encoding):
413412
"""Parse the 'Field Descriptor' (Metadata) packet.
414413
415414
This is compatible with MySQL 4.1+ (not compatible with MySQL 4.0).
@@ -1433,21 +1432,30 @@ def _get_descriptions(self):
14331432
self.fields = []
14341433
self.converters = []
14351434
use_unicode = self.connection.use_unicode
1435+
conn_encoding = self.connection.encoding
14361436
description = []
1437+
14371438
for i in range_type(self.field_count):
14381439
field = self.connection._read_packet(FieldDescriptorPacket)
14391440
self.fields.append(field)
14401441
description.append(field.description())
14411442
field_type = field.type_code
14421443
if use_unicode:
1443-
if field_type in TEXT_TYPES:
1444-
charset = charset_by_id(field.charsetnr)
1445-
if charset.is_binary:
1444+
if field_type == FIELD_TYPE.JSON:
1445+
# When SELECT from JSON column: charset = binary
1446+
# When SELECT CAST(... AS JSON): charset = connection encoding
1447+
# This behavior is different from TEXT / BLOB.
1448+
# We should decode result by connection encoding regardless charsetnr.
1449+
# See https://github.com/PyMySQL/PyMySQL/issues/488
1450+
encoding = conn_encoding # SELECT CAST(... AS JSON)
1451+
elif field_type in TEXT_TYPES:
1452+
if field.charsetnr == 63: # binary
14461453
# TEXTs with charset=binary means BINARY types.
14471454
encoding = None
14481455
else:
1449-
encoding = charset.encoding
1456+
encoding = conn_encoding
14501457
else:
1458+
# Integers, Dates and Times, and other basic data is encoded in ascii
14511459
encoding = 'ascii'
14521460
else:
14531461
encoding = None

0 commit comments

Comments
 (0)
0