Skip to content

Commit 57d06cd

Browse files
committed
fix bug signedness parse All Column Order
1 parent 825f21f commit 57d06cd

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventDataDeserializer.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import com.github.shyiko.mysql.binlog.io.ByteArrayInputStream;
2121

2222
import java.io.IOException;
23+
import java.util.ArrayList;
24+
import java.util.List;
2325

2426
/**
2527
* @author <a href="mailto:stanley.shyiko@gmail.com">Stanley Shyiko</a>
@@ -47,13 +49,35 @@ public TableMapEventData deserialize(ByteArrayInputStream inputStream) throws IO
4749
metadata = metadataDeserializer.deserialize(
4850
new ByteArrayInputStream(inputStream.read(metadataLength)),
4951
eventData.getColumnTypes().length,
50-
numericColumnCount(eventData.getColumnTypes())
52+
numericColumnCount(eventData.getColumnTypes()),
53+
numericColumnIndex(eventData.getColumnTypes())
5154
);
5255
}
5356
eventData.setEventMetadata(metadata);
5457
return eventData;
5558
}
5659

60+
private List<Integer> numericColumnIndex(byte[] types){
61+
ArrayList<Integer> numericColumnIndexList = new ArrayList<>();
62+
for (int i = 0; i < types.length; i++) {
63+
switch (ColumnType.byCode(types[i] & 0xff)) {
64+
case TINY:
65+
case SHORT:
66+
case INT24:
67+
case LONG:
68+
case LONGLONG:
69+
case NEWDECIMAL:
70+
case FLOAT:
71+
case DOUBLE:
72+
case YEAR:
73+
numericColumnIndexList.add(i);
74+
break;
75+
default:
76+
break;
77+
}
78+
}
79+
return numericColumnIndexList;
80+
}
5781
private int numericColumnCount(byte[] types) {
5882
int count = 0;
5983
for (int i = 0; i < types.length; i++) {

src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventMetadataDeserializer.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ public class TableMapEventMetadataDeserializer {
3636

3737
private final Logger logger = Logger.getLogger(getClass().getName());
3838

39-
public TableMapEventMetadata deserialize(ByteArrayInputStream inputStream, int nColumns, int nNumericColumns) throws IOException {
39+
public TableMapEventMetadata deserialize(ByteArrayInputStream inputStream, int nColumns,
40+
int nNumericColumns, List<Integer> numericColumIdxList)
41+
throws IOException {
42+
4043
int remainingBytes = inputStream.available();
4144
if (remainingBytes <= 0) {
4245
return null;
@@ -65,7 +68,8 @@ public TableMapEventMetadata deserialize(ByteArrayInputStream inputStream, int n
6568

6669
switch (fieldType) {
6770
case SIGNEDNESS:
68-
result.setSignedness(readBooleanList(inputStream, nNumericColumns));
71+
result.setSignedness(
72+
convertColumnOrder(readBooleanList(inputStream, nNumericColumns), numericColumIdxList));
6973
break;
7074
case DEFAULT_CHARSET:
7175
result.setDefaultCharset(readDefaultCharset(inputStream));
@@ -108,6 +112,26 @@ public TableMapEventMetadata deserialize(ByteArrayInputStream inputStream, int n
108112
return result;
109113
}
110114

115+
private static BitSet convertColumnOrder(BitSet numericOrderBitSet, List<Integer> numericColumIdxList) {
116+
// case SIGNEDNESS The order of the index in the packet is only the index between the numeric_columns.
117+
// So we need to map the index to the index in the all columns.
118+
Map<Integer, Integer> mappingColumnOrderMap = new HashMap<>();
119+
120+
for (int numericColumnOrder = 0; numericColumnOrder < numericColumIdxList.size();
121+
numericColumnOrder++) {
122+
int allColumnIndex = numericColumIdxList.get(numericColumnOrder);
123+
mappingColumnOrderMap.put(numericColumnOrder, allColumnIndex);
124+
}
125+
126+
BitSet columnOrderBitSet = new BitSet();
127+
for (int i = 0; i < numericOrderBitSet.length(); i++) {
128+
int numericColumnOrder = numericOrderBitSet.nextSetBit(i);
129+
int allColumnIndex = mappingColumnOrderMap.get(numericColumnOrder);
130+
columnOrderBitSet.set(allColumnIndex);
131+
}
132+
return columnOrderBitSet;
133+
}
134+
111135
private static BitSet readBooleanList(ByteArrayInputStream inputStream, int length) throws IOException {
112136
BitSet result = new BitSet();
113137
// according to MySQL internals the amount of storage required for N columns is INT((N+7)/8) bytes

src/test/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventMetadataDeserializerTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.testng.annotations.Test;
66

77
import java.io.IOException;
8+
import java.util.Arrays;
89
import java.util.LinkedHashMap;
910
import java.util.Map;
1011

@@ -29,7 +30,7 @@ public void deserialize() throws IOException {
2930
byte[] metadataIncludingUnknownFieldType = {1, 2, 0, -128, 2, 9, 83, 6, 63, 7, 63, 8, 63, 9, 63};
3031
TableMapEventMetadataDeserializer deserializer = new TableMapEventMetadataDeserializer();
3132
TableMapEventMetadata tableMapEventMetadata =
32-
deserializer.deserialize(new ByteArrayInputStream(metadataIncludingUnknownFieldType), 23, 8);
33+
deserializer.deserialize(new ByteArrayInputStream(metadataIncludingUnknownFieldType), 23, 8, Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7)); // suppose there numeric Columns Idx are 0, 1, 2, 3, 4, 5, 6, 7
3334

3435
Map<Integer, Integer> expectedCharsetCollations = new LinkedHashMap<>();
3536
expectedCharsetCollations.put(6, 63);

0 commit comments

Comments
 (0)