Skip to content

Commit 8949087

Browse files
committed
TestCase resolved
test case resolved Test Case resolved
1 parent 8a0280b commit 8949087

File tree

4 files changed

+82
-105
lines changed

4 files changed

+82
-105
lines changed

pymysqlreplication/constants/CHARSET.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def by_name(self, name, dbms="mysql"):
5959
) as f:
6060
f.readline() # pass header
6161
for line in f:
62-
lines = line.split(",")
62+
lines = line.rstrip("\n").split(",")
6363
if len(lines) != 5:
6464
continue
6565

pymysqlreplication/row_event.py

+5-17
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,15 @@ def charset_to_encoding(name):
259259

260260
def __read_string(self, size, column):
261261
string = self.packet.read_length_coded_pascal_string(size)
262+
origin_string = string
262263
if column.character_set_name is not None:
263264
encoding = self.charset_to_encoding(column.character_set_name)
264265
decode_errors = "ignore" if self._ignore_decode_errors else "strict"
265266
try:
266267
string = string.decode(encoding, decode_errors)
267268
except LookupError:
268-
# If python does not support Mysql encoding type ex)swe7 it will not decoding
269-
string = string.decode(errors=decode_errors)
269+
# python does not support Mysql encoding type ex)swe7 it will not decoding then Show origin string
270+
string = origin_string
270271
return string
271272

272273
def __read_bit(self, column):
@@ -688,13 +689,6 @@ def __init__(self, from_packet, event_size, table_map, ctl_connection, **kwargs)
688689
self.table_obj = Table(self.table_id, self.schema, self.table, self.columns)
689690
table_map[self.table_id] = self.table_obj
690691
self.optional_metadata = self._get_optional_meta_data()
691-
692-
# We exclude 'CHAR' and 'INTERVAL' as they map to 'TINY' and 'ENUM' respectively
693-
self.reverse_field_type = {
694-
v: k
695-
for k, v in vars(FIELD_TYPE).items()
696-
if isinstance(v, int) and k not in ["CHAR", "INTERVAL"]
697-
}
698692
self._sync_column_info()
699693

700694
def get_table(self):
@@ -810,7 +804,6 @@ def _sync_column_info(self):
810804
if not self.__optional_meta_data:
811805
# If optional_meta_data is False Do not sync Event Time Column Schemas
812806
return
813-
814807
charset_pos = 0
815808
enum_or_set_pos = 0
816809
enum_pos = 0
@@ -825,11 +818,9 @@ def _sync_column_info(self):
825818
if self._is_character_column(column_type, dbms=self.dbms):
826819
charset_id = self.optional_metadata.charset_collation_list[charset_pos]
827820
charset_pos += 1
828-
829821
encode_name, collation_name, charset_name = find_charset(
830-
charset_id, dbms=self.dbms
822+
str(charset_id), dbms=self.dbms
831823
)
832-
833824
self.columns[column_idx].collation_name = collation_name
834825
self.columns[column_idx].character_set_name = encode_name
835826

@@ -840,7 +831,7 @@ def _sync_column_info(self):
840831
enum_or_set_pos += 1
841832

842833
encode_name, collation_name, charset_name = find_charset(
843-
charset_id, dbms=self.dbms
834+
str(charset_id), dbms=self.dbms
844835
)
845836

846837
self.columns[column_idx].collation_name = collation_name
@@ -1049,9 +1040,6 @@ def _is_numeric_column(column_type):
10491040
return True
10501041
return False
10511042

1052-
def _get_field_type_key(self, field_type_value):
1053-
return self.reverse_field_type.get(field_type_value, None)
1054-
10551043

10561044
def find_encoding(charset: CHARSET.Charset):
10571045
encode = None

pymysqlreplication/tests/test_basic.py

+46-50
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,12 @@ def create_binlog_packet_wrapper(pkt):
605605

606606

607607
class TestMultipleRowBinLogStreamReader(base.PyMySQLReplicationTestCase):
608+
def setUp(self):
609+
super(TestMultipleRowBinLogStreamReader, self).setUp()
610+
if self.isMySQL8014AndMore():
611+
self.execute("SET GLOBAL binlog_row_metadata='FULL';")
612+
self.execute("SET GLOBAL binlog_row_image='FULL';")
613+
608614
def ignoredEvents(self):
609615
return [GtidEvent, PreviousGtidsEvent]
610616

@@ -714,45 +720,40 @@ def test_delete_multiple_row_event(self):
714720
self.assertEqual(event.rows[1]["values"]["id"], 2)
715721
self.assertEqual(event.rows[1]["values"]["data"], "World")
716722

717-
# erase temporary
718-
# def test_ignore_decode_errors(self):
719-
# problematic_unicode_string = (
720-
# b'[{"text":"\xed\xa0\xbd \xed\xb1\x8d Some string"}]'
721-
# )
722-
# self.stream.close()
723-
# self.execute("CREATE TABLE test (data VARCHAR(50) CHARACTER SET utf8mb4)")
724-
# self.execute_with_args(
725-
# "INSERT INTO test (data) VALUES (%s)", (problematic_unicode_string)
726-
# )
727-
# self.execute("COMMIT")
728-
#
729-
# # Initialize with ignore_decode_errors=False
730-
# self.stream = BinLogStreamReader(
731-
# self.database,
732-
# server_id=1024,
733-
# only_events=(WriteRowsEvent,),
734-
# ignore_decode_errors=False,
735-
# )
736-
# event = self.stream.fetchone()
737-
# event = self.stream.fetchone()
738-
# with self.assertRaises(UnicodeError):
739-
# event = self.stream.fetchone()
740-
# if event.table_map[event.table_id].column_name_flag:
741-
# data = event.rows[0]["values"]["data"]
742-
#
743-
# # Initialize with ignore_decode_errors=True
744-
# self.stream = BinLogStreamReader(
745-
# self.database,
746-
# server_id=1024,
747-
# only_events=(WriteRowsEvent,),
748-
# ignore_decode_errors=True,
749-
# )
750-
# self.stream.fetchone()
751-
# self.stream.fetchone()
752-
# event = self.stream.fetchone()
753-
# if event.table_map[event.table_id].column_name_flag:
754-
# data = event.rows[0]["values"]["data"]
755-
# self.assertEqual(data, '[{"text":" Some string"}]')
723+
def test_ignore_decode_errors(self):
724+
problematic_unicode_string = (
725+
b'[{"text":"\xed\xa0\xbd \xed\xb1\x8d Some string"}]'
726+
)
727+
self.stream.close()
728+
self.execute("CREATE TABLE test (data VARCHAR(50) CHARACTER SET utf8mb4)")
729+
self.execute_with_args(
730+
"INSERT INTO test (data) VALUES (%s)", (problematic_unicode_string)
731+
)
732+
self.execute("COMMIT")
733+
734+
# Initialize with ignore_decode_errors=False
735+
self.stream = BinLogStreamReader(
736+
self.database,
737+
server_id=1024,
738+
only_events=(WriteRowsEvent,),
739+
ignore_decode_errors=False,
740+
)
741+
with self.assertRaises(UnicodeError):
742+
event = self.stream.fetchone()
743+
if event.table_map[event.table_id].column_name_flag:
744+
data = event.rows[0]["values"]["data"]
745+
746+
# Initialize with ignore_decode_errors=True
747+
self.stream = BinLogStreamReader(
748+
self.database,
749+
server_id=1024,
750+
only_events=(WriteRowsEvent,),
751+
ignore_decode_errors=True,
752+
)
753+
event = self.stream.fetchone()
754+
if event.table_map[event.table_id].column_name_flag:
755+
data = event.rows[0]["values"]["data"]
756+
self.assertEqual(data, '[{"text":" Some string"}]')
756757

757758
def test_drop_column(self):
758759
self.stream.close()
@@ -774,15 +775,15 @@ def test_drop_column(self):
774775
finally:
775776
self.resetBinLog()
776777

777-
@unittest.expectedFailure
778778
def test_alter_column(self):
779+
if not self.isMySQL8014AndMore():
780+
self.skipTest("Mysql version is under 8.0.14 - pass")
779781
self.stream.close()
780782
self.execute(
781783
"CREATE TABLE test_alter_column (id INTEGER(11), data VARCHAR(50))"
782784
)
783785
self.execute("INSERT INTO test_alter_column VALUES (1, 'A value')")
784786
self.execute("COMMIT")
785-
# this is a problem only when column is added in position other than at the end
786787
self.execute(
787788
"ALTER TABLE test_alter_column ADD COLUMN another_data VARCHAR(50) AFTER id"
788789
)
@@ -796,16 +797,11 @@ def test_alter_column(self):
796797
server_id=1024,
797798
only_events=(WriteRowsEvent,),
798799
)
799-
event = self.stream.fetchone() # insert with two values
800-
# both of these asserts fail because of issue underlying proble described in issue #118
801-
# because it got table schema info after the alter table, it wrongly assumes the second
802-
# column of the first insert is 'another_data'
803-
# ER: {'id': 1, 'data': 'A value'}
804-
# AR: {'id': 1, 'another_data': 'A value'}
805-
self.assertIn("data", event.rows[0]["values"])
806-
self.assertNot("another_data", event.rows[0]["values"])
800+
event = self.stream.fetchone()
801+
self.assertEqual(event.rows[0]["values"]["data"], "A value")
802+
event = self.stream.fetchone() # insert with three values
803+
self.assertEqual(event.rows[0]["values"]["another_data"], "Another value")
807804
self.assertEqual(event.rows[0]["values"]["data"], "A value")
808-
self.stream.fetchone() # insert with three values
809805

810806

811807
class TestCTLConnectionSettings(base.PyMySQLReplicationTestCase):

pymysqlreplication/tests/test_data_type.py

+30-37
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import sys
66
import json
77

8+
from pymysqlreplication import BinLogStreamReader
9+
810
if sys.version_info < (2, 7):
911
import unittest2 as unittest
1012
else:
@@ -34,6 +36,12 @@ def encode_value(v):
3436

3537

3638
class TestDataType(base.PyMySQLReplicationTestCase):
39+
def setUp(self):
40+
super(TestDataType, self).setUp()
41+
if self.isMySQL8014AndMore():
42+
self.execute("SET GLOBAL binlog_row_metadata='FULL';")
43+
self.execute("SET GLOBAL binlog_row_image='FULL';")
44+
3745
def ignoredEvents(self):
3846
return [GtidEvent, PreviousGtidsEvent]
3947

@@ -104,20 +112,6 @@ def create_and_get_tablemap_event(self, bit):
104112

105113
return event
106114

107-
def test_varbinary(self):
108-
create_query = "CREATE TABLE test(b VARBINARY(4))"
109-
insert_query = "INSERT INTO test VALUES(UNHEX('ff010000'))"
110-
event = self.create_and_insert_value(create_query, insert_query)
111-
if event.table_map[event.table_id].column_name_flag:
112-
self.assertEqual(event.rows[0]["values"]["b"], b"\xff\x01\x00\x00")
113-
114-
def test_fixed_length_binary(self):
115-
create_query = "CREATE TABLE test(b BINARY(4))"
116-
insert_query = "INSERT INTO test VALUES(UNHEX('ff010000'))"
117-
event = self.create_and_insert_value(create_query, insert_query)
118-
if event.table_map[event.table_id].column_name_flag:
119-
self.assertEqual(event.rows[0]["values"]["b"], b"\xff\x01\x00\x00")
120-
121115
def test_decimal(self):
122116
create_query = "CREATE TABLE test (test DECIMAL(2,1))"
123117
insert_query = "INSERT INTO test VALUES(4.2)"
@@ -539,31 +533,31 @@ def test_tiny_blob(self):
539533
insert_query = "INSERT INTO test VALUES('Hello', 'World')"
540534
event = self.create_and_insert_value(create_query, insert_query)
541535
if event.table_map[event.table_id].column_name_flag:
542-
self.assertEqual(event.rows[0]["values"]["test"], b"Hello")
536+
self.assertEqual(event.rows[0]["values"]["test"], "Hello")
543537
self.assertEqual(event.rows[0]["values"]["test2"], "World")
544538

545539
def test_medium_blob(self):
546540
create_query = "CREATE TABLE test (test MEDIUMBLOB, test2 MEDIUMTEXT) CHARACTER SET latin1 COLLATE latin1_bin;"
547541
insert_query = "INSERT INTO test VALUES('Hello', 'World')"
548542
event = self.create_and_insert_value(create_query, insert_query)
549543
if event.table_map[event.table_id].column_name_flag:
550-
self.assertEqual(event.rows[0]["values"]["test"], b"Hello")
544+
self.assertEqual(event.rows[0]["values"]["test"], "Hello")
551545
self.assertEqual(event.rows[0]["values"]["test2"], "World")
552546

553547
def test_long_blob(self):
554548
create_query = "CREATE TABLE test (test LONGBLOB, test2 LONGTEXT) CHARACTER SET latin1 COLLATE latin1_bin;"
555549
insert_query = "INSERT INTO test VALUES('Hello', 'World')"
556550
event = self.create_and_insert_value(create_query, insert_query)
557551
if event.table_map[event.table_id].column_name_flag:
558-
self.assertEqual(event.rows[0]["values"]["test"], b"Hello")
552+
self.assertEqual(event.rows[0]["values"]["test"], "Hello")
559553
self.assertEqual(event.rows[0]["values"]["test2"], "World")
560554

561555
def test_blob(self):
562556
create_query = "CREATE TABLE test (test BLOB, test2 TEXT) CHARACTER SET latin1 COLLATE latin1_bin;"
563557
insert_query = "INSERT INTO test VALUES('Hello', 'World')"
564558
event = self.create_and_insert_value(create_query, insert_query)
565559
if event.table_map[event.table_id].column_name_flag:
566-
self.assertEqual(event.rows[0]["values"]["test"], b"Hello")
560+
self.assertEqual(event.rows[0]["values"]["test"], "Hello")
567561
self.assertEqual(event.rows[0]["values"]["test2"], "World")
568562

569563
def test_string(self):
@@ -804,25 +798,6 @@ def test_encoding_utf8(self):
804798
if event.table_map[event.table_id].column_name_flag:
805799
self.assertMultiLineEqual(event.rows[0]["values"]["test"], string)
806800

807-
def test_zerofill(self):
808-
create_query = "CREATE TABLE test ( \
809-
test TINYINT UNSIGNED ZEROFILL DEFAULT NULL, \
810-
test2 SMALLINT UNSIGNED ZEROFILL DEFAULT NULL, \
811-
test3 MEDIUMINT UNSIGNED ZEROFILL DEFAULT NULL, \
812-
test4 INT UNSIGNED ZEROFILL DEFAULT NULL, \
813-
test5 BIGINT UNSIGNED ZEROFILL DEFAULT NULL \
814-
)"
815-
insert_query = (
816-
"INSERT INTO test (test, test2, test3, test4, test5) VALUES(1, 1, 1, 1, 1)"
817-
)
818-
event = self.create_and_insert_value(create_query, insert_query)
819-
if event.table_map[event.table_id].column_name_flag:
820-
self.assertEqual(event.rows[0]["values"]["test"], "001")
821-
self.assertEqual(event.rows[0]["values"]["test2"], "00001")
822-
self.assertEqual(event.rows[0]["values"]["test3"], "00000001")
823-
self.assertEqual(event.rows[0]["values"]["test4"], "0000000001")
824-
self.assertEqual(event.rows[0]["values"]["test5"], "00000000000000000001")
825-
826801
def test_partition_id(self):
827802
if not self.isMySQL80AndMore():
828803
self.skipTest("Not supported in this version of MySQL")
@@ -942,6 +917,24 @@ def test_mariadb_only_status_vars(self):
942917

943918
self.assertEqual(event.query, create_query)
944919

920+
def test_varbinary(self):
921+
self.stream.close()
922+
self.stream = BinLogStreamReader(
923+
self.database,
924+
server_id=1024,
925+
only_events=(WriteRowsEvent,),
926+
ignore_decode_errors=True,
927+
)
928+
create_query = "CREATE TABLE test(b VARBINARY(4))"
929+
insert_query = "INSERT INTO test VALUES(UNHEX('ff010000'))"
930+
self.execute(create_query)
931+
self.execute(insert_query)
932+
self.execute("COMMIT")
933+
934+
event = self.stream.fetchone()
935+
if event.table_map[event.table_id].column_name_flag:
936+
self.assertEqual(event.rows[0]["values"]["b"], b"\xff\x01\x00\x00")
937+
945938

946939
if __name__ == "__main__":
947940
unittest.main()

0 commit comments

Comments
 (0)