Skip to content

Commit 175df28

Browse files
Alexander Ignatovbaloo
authored andcommitted
Fix handling of JSON literal values #226 #298
In case of large JSON documents leteral values should be retrieved with `read_uint32` instead of `read_uint32` to avoid further AssertionError
1 parent fa5892d commit 175df28

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

pymysqlreplication/packet.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ def read_offset_or_inline(packet, large):
4343

4444
if t in (JSONB_TYPE_LITERAL,
4545
JSONB_TYPE_INT16, JSONB_TYPE_UINT16):
46-
return (t, None, packet.read_binary_json_type_inlined(t))
46+
return (t, None, packet.read_binary_json_type_inlined(t, large))
4747
if large and t in (JSONB_TYPE_INT32, JSONB_TYPE_UINT32):
48-
return (t, None, packet.read_binary_json_type_inlined(t))
48+
return (t, None, packet.read_binary_json_type_inlined(t, large))
4949

5050
if large:
5151
return (t, packet.read_uint32(), None)
@@ -255,7 +255,7 @@ def read_length_coded_pascal_string(self, size):
255255
def read_variable_length_string(self):
256256
"""Read a variable length string where the first 1-5 bytes stores the
257257
length of the string.
258-
258+
259259
For each byte, the first bit being high indicates another byte must be
260260
read.
261261
"""
@@ -384,9 +384,9 @@ def read_binary_json_type(self, t, length):
384384

385385
raise ValueError('Json type %d is not handled' % t)
386386

387-
def read_binary_json_type_inlined(self, t):
387+
def read_binary_json_type_inlined(self, t, large):
388388
if t == JSONB_TYPE_LITERAL:
389-
value = self.read_uint16()
389+
value = self.read_uint32() if large else self.read_uint16()
390390
if value == JSONB_LITERAL_NULL:
391391
return None
392392
elif value == JSONB_LITERAL_TRUE:

pymysqlreplication/tests/test_data_type.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,16 @@ def test_json_large(self):
469469

470470
self.assertEqual(event.rows[0]["values"]["value"], to_binary_dict(data))
471471

472+
def test_json_large_with_literal(self):
473+
if not self.isMySQL57():
474+
self.skipTest("Json is only supported in mysql 5.7")
475+
data = dict([('foooo%i'%i, 'baaaaar%i'%i) for i in range(2560)], literal=True) # Make it large with literal
476+
create_query = "CREATE TABLE test (id int, value json);"
477+
insert_query = """INSERT INTO test (id, value) VALUES (1, '%s');""" % json.dumps(data)
478+
event = self.create_and_insert_value(create_query, insert_query)
479+
480+
self.assertEqual(event.rows[0]["values"]["value"], to_binary_dict(data))
481+
472482
def test_json_types(self):
473483
if not self.isMySQL57():
474484
self.skipTest("Json is only supported in mysql 5.7")

0 commit comments

Comments
 (0)