Skip to content

Commit 37f91b0

Browse files
committed
Support 'ZEROFILL' attribute for numeric datatypes
1. Search for 'ZEROFILL' in column type 2. Set boolean variable zerofill for column objects 3. Format column values for columns with 'ZEROFILL' attribute + Added and passed data type test
1 parent 3560a69 commit 37f91b0

File tree

4 files changed

+28
-0
lines changed

4 files changed

+28
-0
lines changed

pymysqlreplication/column.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def __parse_column_definition(self, column_type, column_schema, packet):
2222
self.character_set_name = column_schema["CHARACTER_SET_NAME"]
2323
self.comment = column_schema["COLUMN_COMMENT"]
2424
self.unsigned = column_schema["COLUMN_TYPE"].find("unsigned") != -1
25+
self.zerofill = column_schema["COLUMN_TYPE"].find("zerofill") != -1
2526
self.type_is_bool = False
2627
self.is_primary = column_schema["COLUMN_KEY"] == "PRI"
2728

pymysqlreplication/row_event.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ def _read_column_data(self, cols_bitmap):
9292
column = self.columns[i]
9393
name = self.table_map[self.table_id].columns[i].name
9494
unsigned = self.table_map[self.table_id].columns[i].unsigned
95+
zerofill = self.table_map[self.table_id].columns[i].zerofill
9596

9697
if BitGet(cols_bitmap, i) == 0:
9798
values[name] = None
@@ -102,21 +103,29 @@ def _read_column_data(self, cols_bitmap):
102103
elif column.type == FIELD_TYPE.TINY:
103104
if unsigned:
104105
values[name] = struct.unpack("<B", self.packet.read(1))[0]
106+
if zerofill:
107+
values[name] = format(values[name], '03d')
105108
else:
106109
values[name] = struct.unpack("<b", self.packet.read(1))[0]
107110
elif column.type == FIELD_TYPE.SHORT:
108111
if unsigned:
109112
values[name] = struct.unpack("<H", self.packet.read(2))[0]
113+
if zerofill:
114+
values[name] = format(values[name], '05d')
110115
else:
111116
values[name] = struct.unpack("<h", self.packet.read(2))[0]
112117
elif column.type == FIELD_TYPE.LONG:
113118
if unsigned:
114119
values[name] = struct.unpack("<I", self.packet.read(4))[0]
120+
if zerofill:
121+
values[name] = format(values[name], '010d')
115122
else:
116123
values[name] = struct.unpack("<i", self.packet.read(4))[0]
117124
elif column.type == FIELD_TYPE.INT24:
118125
if unsigned:
119126
values[name] = self.packet.read_uint24()
127+
if zerofill:
128+
values[name] = format(values[name], '08d')
120129
else:
121130
values[name] = self.packet.read_int24()
122131
elif column.type == FIELD_TYPE.FLOAT:
@@ -155,6 +164,8 @@ def _read_column_data(self, cols_bitmap):
155164
elif column.type == FIELD_TYPE.LONGLONG:
156165
if unsigned:
157166
values[name] = self.packet.read_uint64()
167+
if zerofill:
168+
values[name] = format(values[name], '020d')
158169
else:
159170
values[name] = self.packet.read_int64()
160171
elif column.type == FIELD_TYPE.YEAR:

pymysqlreplication/tests/test_data_objects.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def test_column_serializable(self):
5656
self.assertIn("character_set_name", serialized)
5757
self.assertIn("comment", serialized)
5858
self.assertIn("unsigned", serialized)
59+
self.assertIn("zerofill", serialized)
5960
self.assertIn("type_is_bool", serialized)
6061
self.assertIn("is_primary", serialized)
6162

pymysqlreplication/tests/test_data_type.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,21 @@ def test_encoding_utf8(self):
609609
event = self.create_and_insert_value(create_query, insert_query)
610610
self.assertMultiLineEqual(event.rows[0]["values"]["test"], string)
611611

612+
def test_zerofill(self):
613+
create_query = "CREATE TABLE test ( \
614+
test TINYINT UNSIGNED ZEROFILL DEFAULT NULL, \
615+
test2 SMALLINT UNSIGNED ZEROFILL DEFAULT NULL, \
616+
test3 MEDIUMINT UNSIGNED ZEROFILL DEFAULT NULL, \
617+
test4 INT UNSIGNED ZEROFILL DEFAULT NULL, \
618+
test5 BIGINT UNSIGNED ZEROFILL DEFAULT NULL \
619+
)"
620+
insert_query = "INSERT INTO test (test, test2, test3, test4, test5) VALUES(1, 1, 1, 1, 1)"
621+
event = self.create_and_insert_value(create_query, insert_query)
622+
self.assertEqual(event.rows[0]["values"]["test"], '001')
623+
self.assertEqual(event.rows[0]["values"]["test2"], '00001')
624+
self.assertEqual(event.rows[0]["values"]["test3"], '00000001')
625+
self.assertEqual(event.rows[0]["values"]["test4"], '0000000001')
626+
self.assertEqual(event.rows[0]["values"]["test5"], '00000000000000000001')
612627

613628
if __name__ == "__main__":
614629
unittest.main()

0 commit comments

Comments
 (0)