Skip to content

Commit feb9221

Browse files
authored
Merge pull request osheroff#41 from gunnarmorling/40
osheroff#40 Adding support for column visibility as supported by MySQL 8.0.23
2 parents 12f1585 + ae3c591 commit feb9221

File tree

6 files changed

+62
-7
lines changed

6 files changed

+62
-7
lines changed

src/main/java/com/github/shyiko/mysql/binlog/event/TableMapEventMetadata.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class TableMapEventMetadata implements EventData {
3636
private Map<Integer, Integer> primaryKeysWithPrefix;
3737
private DefaultCharset enumAndSetDefaultCharset;
3838
private List<Integer> enumAndSetColumnCharsets;
39+
private BitSet visibility;
3940

4041
public BitSet getSignedness() {
4142
return signedness;
@@ -125,6 +126,14 @@ public void setEnumAndSetColumnCharsets(List<Integer> enumAndSetColumnCharsets)
125126
this.enumAndSetColumnCharsets = enumAndSetColumnCharsets;
126127
}
127128

129+
public BitSet getVisibility() {
130+
return visibility;
131+
}
132+
133+
public void setVisibility(BitSet visibility) {
134+
this.visibility = visibility;
135+
}
136+
128137
@Override
129138
public String toString() {
130139
final StringBuilder sb = new StringBuilder();
@@ -163,6 +172,8 @@ public String toString() {
163172
sb.append(", enumAndSetColumnCharsets=").append(enumAndSetColumnCharsets == null ? "null" : "");
164173
appendList(sb, enumAndSetColumnCharsets);
165174

175+
sb.append(",visibility=").append(visibility);
176+
166177
sb.append('}');
167178
return sb.toString();
168179
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public TableMapEventData deserialize(ByteArrayInputStream inputStream) throws IO
4646
if (metadataLength > 0) {
4747
metadata = metadataDeserializer.deserialize(
4848
new ByteArrayInputStream(inputStream.read(metadataLength)),
49+
eventData.getColumnTypes().length,
4950
numericColumnCount(eventData.getColumnTypes())
5051
);
5152
}

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

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@
2626
import java.util.LinkedHashMap;
2727
import java.util.List;
2828
import java.util.Map;
29+
import java.util.logging.Level;
30+
import java.util.logging.Logger;
2931

3032
/**
3133
* @author <a href="mailto:[email protected]">Ahmed Abdul Hamid</a>
3234
*/
3335
public class TableMapEventMetadataDeserializer {
3436

35-
public TableMapEventMetadata deserialize(ByteArrayInputStream inputStream, int nIntColumns) throws IOException {
37+
private final Logger logger = Logger.getLogger(getClass().getName());
38+
39+
public TableMapEventMetadata deserialize(ByteArrayInputStream inputStream, int nColumns, int nNumericColumns) throws IOException {
3640
int remainingBytes = inputStream.available();
3741
if (remainingBytes <= 0) {
3842
return null;
@@ -41,15 +45,21 @@ public TableMapEventMetadata deserialize(ByteArrayInputStream inputStream, int n
4145
TableMapEventMetadata result = new TableMapEventMetadata();
4246

4347
for (; remainingBytes > 0; inputStream.enterBlock(remainingBytes)) {
44-
MetadataFieldType fieldType = MetadataFieldType.byCode(inputStream.readInteger(1));
48+
int code = inputStream.readInteger(1);
49+
50+
MetadataFieldType fieldType = MetadataFieldType.byCode(code);
51+
if (fieldType == null) {
52+
throw new IOException("Unsupported table metadata field type " + code);
53+
}
54+
4555
int fieldLength = inputStream.readPackedInteger();
4656

4757
remainingBytes = inputStream.available();
4858
inputStream.enterBlock(fieldLength);
4959

5060
switch (fieldType) {
5161
case SIGNEDNESS:
52-
result.setSignedness(readSignedness(inputStream, nIntColumns));
62+
result.setSignedness(readBooleanList(inputStream, nNumericColumns));
5363
break;
5464
case DEFAULT_CHARSET:
5565
result.setDefaultCharset(readDefaultCharset(inputStream));
@@ -80,17 +90,24 @@ public TableMapEventMetadata deserialize(ByteArrayInputStream inputStream, int n
8090
break;
8191
case ENUM_AND_SET_COLUMN_CHARSET:
8292
result.setEnumAndSetColumnCharsets(readIntegers(inputStream));
93+
case VISIBILITY:
94+
result.setVisibility(readBooleanList(inputStream, nColumns));
95+
break;
96+
case UNKNOWN_METADATA_FIELD_TYPE:
97+
if (logger.isLoggable(Level.FINE)) {
98+
logger.fine("Received metadata field of unknown type");
99+
}
83100
break;
84101
default:
85102
inputStream.enterBlock(remainingBytes);
86-
throw new IOException("Unsupported table metadata field type " + fieldType);
103+
throw new IOException("Unsupported table metadata field type " + code);
87104
}
88105
remainingBytes -= fieldLength;
89106
}
90107
return result;
91108
}
92109

93-
private static BitSet readSignedness(ByteArrayInputStream inputStream, int length) throws IOException {
110+
private static BitSet readBooleanList(ByteArrayInputStream inputStream, int length) throws IOException {
94111
BitSet result = new BitSet();
95112
// according to MySQL internals the amount of storage required for N columns is INT((N+7)/8) bytes
96113
byte[] bytes = inputStream.read((length + 7) >> 3);
@@ -162,7 +179,9 @@ private enum MetadataFieldType {
162179
SIMPLE_PRIMARY_KEY(8), // The primary key without any prefix
163180
PRIMARY_KEY_WITH_PREFIX(9), // The primary key with some prefix
164181
ENUM_AND_SET_DEFAULT_CHARSET(10), // Charsets of ENUM and SET columns
165-
ENUM_AND_SET_COLUMN_CHARSET(11); // Charsets of ENUM and SET columns
182+
ENUM_AND_SET_COLUMN_CHARSET(11), // Charsets of ENUM and SET columns
183+
VISIBILITY(12), // Column visibility (8.0.23 and newer)
184+
UNKNOWN_METADATA_FIELD_TYPE(128); // Returned with binlog-row-metadata=FULL from MySQL 8.0 in some cases
166185

167186
private final int code;
168187

src/test/java/com/github/shyiko/mysql/binlog/BinaryLogClientIntegrationTest.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ public class BinaryLogClientIntegrationTest {
115115
protected MysqlVersion mysqlVersion;
116116

117117
protected MysqlOnetimeServerOptions getOptions() {
118-
return null;
118+
MysqlOnetimeServerOptions options = new MysqlOnetimeServerOptions();
119+
options.fullRowMetaData = true;
120+
return options;
119121
}
120122

121123
@BeforeClass
@@ -1140,6 +1142,21 @@ public void execute(final ResultSet rs) throws SQLException {
11401142
});
11411143
}
11421144

1145+
@Test
1146+
public void testMySQL8InvisibleColumn() throws Exception {
1147+
if ( !mysqlVersion.atLeast(8, 0) )
1148+
throw new SkipException("skipping mysql8 invisible column test");
1149+
1150+
master.execute("drop table if exists test_invisible_column");
1151+
master.execute("create table test_invisible_column (\n"
1152+
+ "id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n"
1153+
+ "name varchar(100) not null,\n"
1154+
+ "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP INVISIBLE\n"
1155+
+ ");");
1156+
master.execute("insert into test_invisible_column (name) values ('User 1')");
1157+
eventListener.waitFor(WriteRowsEventData.class, 1, DEFAULT_TIMEOUT);
1158+
}
1159+
11431160
@AfterMethod
11441161
public void afterEachTest() throws Exception {
11451162
final CountDownLatch latch = new CountDownLatch(1);

src/test/java/com/github/shyiko/mysql/binlog/MysqlOnetimeServer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ public void boot() throws Exception {
6363
authPlugin = "--default-authentication-plugin=mysql_native_password";
6464
}
6565

66+
String fullRowMetaData = "";
67+
if ( getVersion().atLeast(8, 0) && options.fullRowMetaData ) {
68+
fullRowMetaData = "--binlog-row-metadata=FULL";
69+
}
70+
6671
ProcessBuilder pb = new ProcessBuilder(
6772
dir + "/src/test/onetimeserver",
6873
"--mysql-version=" + getVersionString(),
@@ -74,6 +79,7 @@ public void boot() throws Exception {
7479
"--character-set-server=utf8",
7580
"--sync_binlog=0",
7681
"--default-time-zone=+00:00",
82+
fullRowMetaData,
7783
isRoot ? "--user=root" : "",
7884
authPlugin,
7985
gtidParams

src/test/java/com/github/shyiko/mysql/binlog/MysqlOnetimeServerOptions.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ public class MysqlOnetimeServerOptions {
55
public boolean gtid = false;
66
public MysqlOnetimeServer masterServer;
77
public String extraParams;
8+
public boolean fullRowMetaData;
89
}

0 commit comments

Comments
 (0)