Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d2ef033

Browse files
authored
Merge pull request #602 from dongwook-chan/fix/rows-query-parsing
Fix parsing of query field of RowsQueryEvent
2 parents fb82d6d + 7d1cc41 commit d2ef033

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

‎pymysqlreplication/event.py‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -872,20 +872,18 @@ class RowsQueryLogEvent(BinLogEvent):
872872
More details are available in the MySQL Knowledge Base:
873873
https://dev.mysql.com/doc/dev/mysql-server/latest/classRows__query__log__event.html
874874
875-
:ivar query_length: uint - Length of the SQL statement
876875
:ivar query: str - The executed SQL statement
877876
"""
878877

879878
def __init__(self, from_packet, event_size, table_map, ctl_connection, **kwargs):
880879
super(RowsQueryLogEvent, self).__init__(
881880
from_packet, event_size, table_map, ctl_connection, **kwargs
882881
)
883-
self.query_length=self.packet.read_uint8()
884-
self.query = self.packet.read(self.query_length).decode("utf-8")
882+
self.packet.advance(1)
883+
self.query = self.packet.read_available().decode("utf-8")
885884

886885
def dump(self):
887886
print(f"=== {self.__class__.__name__} ===")
888-
print(f"Query length: {self.query_length}")
889887
print(f"Query: {self.query}")
890888

891889

‎pymysqlreplication/packet.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from pymysqlreplication import constants, event, row_event
22
from pymysqlreplication.json_binary import parse_json, JsonDiff, JsonDiffOperation
33
from pymysqlreplication.util.bytes import *
4+
from pymysqlreplication.constants import BINLOG
45

56
# Constants from PyMYSQL source code
67
NULL_COLUMN = 251
@@ -384,3 +385,6 @@ def read_string(self):
384385

385386
def bytes_to_read(self):
386387
return len(self.packet._data) - self.packet._position
388+
389+
def read_available(self):
390+
return self.packet.read(self.bytes_to_read() - BINLOG.BINLOG_CHECKSUM_LEN)

‎pymysqlreplication/tests/test_basic.py‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,36 @@ def test_rows_query_log_event(self):
15671567
event = self.stream.fetchone()
15681568
self.assertIsInstance(event, RowsQueryLogEvent)
15691569

1570+
def test_long_query(self):
1571+
"""
1572+
Address issue #601
1573+
Do not use the first byte of the body to determine the length of the query.
1574+
1 byte can not represent the length of a query that is longer than 255 bytes.
1575+
"""
1576+
1577+
self.stream.close()
1578+
self.stream = BinLogStreamReader(
1579+
self.database,
1580+
server_id=1024,
1581+
only_events=[RowsQueryLogEvent],
1582+
)
1583+
1584+
self.execute(
1585+
"CREATE TABLE IF NOT EXISTS test (id INT AUTO_INCREMENT PRIMARY KEY, long_text VARCHAR(256))"
1586+
)
1587+
long_query = (
1588+
"INSERT INTO test (long_text) VALUES ('"
1589+
"What is the longest word in english?"
1590+
"Pneumonoultramicroscopicsilicovolcanoconiosis is the longest word in the English language."
1591+
"This text has 256 characters and hence its length can not be represented in a single byte."
1592+
"')"
1593+
)
1594+
self.execute(long_query)
1595+
self.execute("COMMIT")
1596+
event = self.stream.fetchone()
1597+
self.assertIsInstance(event, RowsQueryLogEvent)
1598+
self.assertEqual(event.query, long_query)
1599+
15701600

15711601
class TestLatin1(base.PyMySQLReplicationTestCase):
15721602
def setUp(self):

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /