Skip to content

Commit 13ddcc4

Browse files
Add test for the Write a test for MySQL 5.7 column name support
1 parent dc92e50 commit 13ddcc4

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ Other contributors:
364364
- Oliver Seemann: Handle large json, github actions,
365365
Zero-pad fixed-length binary fields (https://github.com/oseemann)
366366
- Mahadir Ahmad: Handle null json payload (https://github.com/mahadirz)
367+
- Mehmet Kartalbas: Add MySQL 5.7 column name support (https://github.com/kartalbas)
367368
- Axel Viala: Removal of Python 2.7 (https://github.com/darnuria)
368369
- Etern: Add XAPrepareEvent, parse last_committed & sequence_number of GtidEvent (https://github.com/etern)
369370
- Jason Fulghum: typo in ident variable name (https://github.com/fulghum)

pymysqlreplication/tests/base.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ def isMySQL57(self):
8989
version = float(self.getMySQLVersion().rsplit(".", 1)[0])
9090
return version == 5.7
9191

92+
def isMySQL57AndMore(self):
93+
if self.isMariaDB():
94+
return False
95+
version = float(self.getMySQLVersion().rsplit(".", 1)[0])
96+
return version >= 5.7
97+
9298
def isMySQL80AndMore(self):
9399
if self.isMariaDB():
94100
return False

pymysqlreplication/tests/test_basic.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,75 @@ def test_write_row_event(self):
271271
self.assertEqual(event.rows[0]["values"]["data"], "Hello World")
272272
self.assertEqual(event.columns[1].name, "data")
273273

274+
def test_fetch_column_names_from_schema(self):
275+
# This test is for MySQL 5.7+
276+
if not self.isMySQL57AndMore():
277+
self.skipTest("Test for MySQL 5.7+ where binlog_row_metadata can be MINIMAL")
278+
279+
self.execute("SET SESSION binlog_row_metadata = 'MINIMAL'")
280+
query = "CREATE TABLE test_column_cache (id INT NOT NULL AUTO_INCREMENT, data VARCHAR (50) NOT NULL, PRIMARY KEY (id))"
281+
self.execute(query)
282+
self.execute("INSERT INTO test_column_cache (data) VALUES('Hello')")
283+
self.execute("COMMIT")
284+
285+
# Test with use_column_name_cache = True
286+
self.stream.close()
287+
self.stream = BinLogStreamReader(
288+
self.database,
289+
server_id=1024,
290+
use_column_name_cache=True,
291+
only_events=[WriteRowsEvent],
292+
)
293+
294+
event = self.stream.fetchone()
295+
self.assertIsInstance(event, WriteRowsEvent)
296+
self.assertEqual(event.table, "test_column_cache")
297+
self.assertIn("id", event.rows[0]["values"])
298+
self.assertIn("data", event.rows[0]["values"])
299+
self.assertEqual(event.rows[0]["values"]["id"], 1)
300+
self.assertEqual(event.rows[0]["values"]["data"], "Hello")
301+
302+
# Test with use_column_name_cache = False
303+
self.stream.close()
304+
305+
# Clear cache before next run
306+
from pymysqlreplication import row_event
307+
row_event._COLUMN_NAME_CACHE.clear()
308+
309+
self.stream = BinLogStreamReader(
310+
self.database,
311+
server_id=1025, # different server_id to avoid caching issues
312+
use_column_name_cache=False,
313+
only_events=[WriteRowsEvent],
314+
)
315+
316+
# Reset and replay events
317+
self.resetBinLog()
318+
self.execute("SET SESSION binlog_row_metadata = 'MINIMAL'")
319+
self.execute("INSERT INTO test_column_cache (data) VALUES('World')")
320+
self.execute("COMMIT")
321+
322+
# Skip RotateEvent and FormatDescriptionEvent
323+
self.stream.fetchone()
324+
self.stream.fetchone()
325+
# Skip QueryEvent for BEGIN
326+
if not self.isMariaDB():
327+
self.stream.fetchone()
328+
# Skip TableMapEvent
329+
self.stream.fetchone()
330+
331+
event = self.stream.fetchone()
332+
self.assertIsInstance(event, WriteRowsEvent)
333+
self.assertEqual(event.table, "test_column_cache")
334+
# With cache disabled, we should not have column names
335+
self.assertNotIn("id", event.rows[0]["values"])
336+
self.assertNotIn("data", event.rows[0]["values"])
337+
338+
# cleanup
339+
self.execute("SET SESSION binlog_row_metadata = 'FULL'")
340+
row_event._COLUMN_NAME_CACHE.clear()
341+
342+
274343
def test_delete_row_event(self):
275344
query = "CREATE TABLE test (id INT NOT NULL AUTO_INCREMENT, data VARCHAR (50) NOT NULL, PRIMARY KEY (id))"
276345
self.execute(query)

0 commit comments

Comments
 (0)