diff --git a/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/ColumnType.java b/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/ColumnType.java
index cc8c9415..1a44490f 100644
--- a/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/ColumnType.java
+++ b/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/ColumnType.java
@@ -45,6 +45,9 @@ public enum ColumnType {
TIMESTAMP_V2(17),
DATETIME_V2(18),
TIME_V2(19),
+ // MYSQL_TYPE_TYPED_ARRAY data type appeared in MySQL 8.0.18+
+ // @see https://github.com/mysql/mysql-server/commit/9082b6a820f3948fd563cc32a050f5e8775f2855
+ TYPED_ARRAY(20),
JSON(245),
NEWDECIMAL(246),
ENUM(247),
diff --git a/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventDataDeserializer.java b/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventDataDeserializer.java
index 6cb814cb..a1d0046d 100644
--- a/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventDataDeserializer.java
+++ b/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventDataDeserializer.java
@@ -21,6 +21,8 @@
import java.io.IOException;
+import static com.github.shyiko.mysql.binlog.event.deserialization.ColumnType.TYPED_ARRAY;
+
/**
* @author Stanley Shyiko
*/
@@ -78,7 +80,12 @@ private int numericColumnCount(byte[] types) {
private int[] readMetadata(ByteArrayInputStream inputStream, byte[] columnTypes) throws IOException {
int[] metadata = new int[columnTypes.length];
for (int i = 0; i < columnTypes.length; i++) {
- switch(ColumnType.byCode(columnTypes[i] & 0xFF)) {
+ ColumnType columnType = ColumnType.byCode(columnTypes[i] & 0xFF);
+ if (columnType == TYPED_ARRAY) {
+ byte[] arrayType = inputStream.read(1);
+ columnType = ColumnType.byCode(arrayType[0] & 0xFF);
+ }
+ switch(columnType) {
case FLOAT:
case DOUBLE:
case BLOB:
diff --git a/src/test/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventDataDeserializerTest.java b/src/test/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventDataDeserializerTest.java
new file mode 100644
index 00000000..7431b68d
--- /dev/null
+++ b/src/test/java/com/github/shyiko/mysql/binlog/event/deserialization/TableMapEventDataDeserializerTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2017 Juan Olivares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.shyiko.mysql.binlog.event.deserialization;
+
+import com.github.shyiko.mysql.binlog.event.TableMapEventData;
+import com.github.shyiko.mysql.binlog.event.TableMapEventMetadata;
+import com.github.shyiko.mysql.binlog.io.ByteArrayInputStream;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.BitSet;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tests for {@link TableMapEventDataDeserializer}.
+ */
+public class TableMapEventDataDeserializerTest {
+ @Test
+ public void deserialize() throws IOException {
+ TableMapEventDataDeserializer deserializer = new TableMapEventDataDeserializer();
+ // The Table_map_event data. See its format at
+ // https://dev.mysql.com/doc/dev/mysql-server/latest/classbinary__log_1_1Table__map__event.html
+ byte[] data = {
+ // table_id : 6 bytes
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ // flags : 2 bytes
+ 1,
+ 0,
+ // database_name string length : 1 byte
+ 6,
+ // database_name null-terminated string, end with 0
+ 116,
+ 101,
+ 115,
+ 116,
+ 68,
+ 98,
+ 0,
+ // table_name string length : 1 byte
+ 9,
+ // table_name null-terminated string, end with 0
+ 116,
+ 101,
+ 115,
+ 116,
+ 84,
+ 97,
+ 98,
+ 108,
+ 101,
+ 0,
+ // column_count
+ 3,
+ // column_type list
+ 8,
+ 1,
+ 20,
+ // metadata_length
+ 1,
+ // metadata
+ 8,
+ // null_bits
+ 80,
+ // optional metadata fields stored in Type, Length, Value(TLV) format.
+ // Type takes 1 byte. Length is a packed integer value. Values takes Length bytes.
+
+ // SIGNEDNESS
+ 1,
+ 1,
+ 0,
+ // DEFAULT_CHARSET
+ 2,
+ 1,
+ 45
+ };
+ TableMapEventData eventData = deserializer.deserialize(new ByteArrayInputStream(data));
+ assertEquals(eventData.toString(), getExpectedEventData().toString());
+ }
+
+ private TableMapEventData getExpectedEventData() {
+ TableMapEventData eventData = new TableMapEventData();
+ // table_id
+ eventData.setTableId(1);
+ // database_name
+ eventData.setDatabase("testDb");
+ // table_name
+ eventData.setTable("testTable");
+
+ // column_type
+ // 3 column types: MYSQL_TYPE_LONGLONG, MYSQL_TYPE_TINY, MYSQL_TYPE_TYPED_ARRAY
+ eventData.setColumnTypes(new byte[] {8, 1, 20});
+
+ // metadata of the column types
+ eventData.setColumnMetadata(new int[] {0, 0, 0});
+
+ // null_bits
+ eventData.setColumnNullability(new BitSet());
+
+ // optional metadata fields
+ TableMapEventMetadata metadata = new TableMapEventMetadata();
+ metadata.setSignedness(new BitSet());
+ TableMapEventMetadata.DefaultCharset charset = new TableMapEventMetadata.DefaultCharset();
+ charset.setDefaultCharsetCollation(45);
+ metadata.setDefaultCharset(charset);
+ eventData.setEventMetadata(metadata);
+ return eventData;
+ }
+}