@@ -88,7 +88,6 @@ def _makefile(sock, mode):
88
88
FIELD_TYPE .BLOB ,
89
89
FIELD_TYPE .LONG_BLOB ,
90
90
FIELD_TYPE .MEDIUM_BLOB ,
91
- FIELD_TYPE .JSON ,
92
91
FIELD_TYPE .STRING ,
93
92
FIELD_TYPE .TINY_BLOB ,
94
93
FIELD_TYPE .VAR_STRING ,
@@ -407,9 +406,9 @@ class FieldDescriptorPacket(MysqlPacket):
407
406
408
407
def __init__ (self , data , encoding ):
409
408
MysqlPacket .__init__ (self , data , encoding )
410
- self .__parse_field_descriptor (encoding )
409
+ self ._parse_field_descriptor (encoding )
411
410
412
- def __parse_field_descriptor (self , encoding ):
411
+ def _parse_field_descriptor (self , encoding ):
413
412
"""Parse the 'Field Descriptor' (Metadata) packet.
414
413
415
414
This is compatible with MySQL 4.1+ (not compatible with MySQL 4.0).
@@ -1433,21 +1432,30 @@ def _get_descriptions(self):
1433
1432
self .fields = []
1434
1433
self .converters = []
1435
1434
use_unicode = self .connection .use_unicode
1435
+ conn_encoding = self .connection .encoding
1436
1436
description = []
1437
+
1437
1438
for i in range_type (self .field_count ):
1438
1439
field = self .connection ._read_packet (FieldDescriptorPacket )
1439
1440
self .fields .append (field )
1440
1441
description .append (field .description ())
1441
1442
field_type = field .type_code
1442
1443
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
1446
1453
# TEXTs with charset=binary means BINARY types.
1447
1454
encoding = None
1448
1455
else :
1449
- encoding = charset . encoding
1456
+ encoding = conn_encoding
1450
1457
else :
1458
+ # Integers, Dates and Times, and other basic data is encoded in ascii
1451
1459
encoding = 'ascii'
1452
1460
else :
1453
1461
encoding = None
0 commit comments