diff --git a/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/AbstractRowsEventDataDeserializer.java b/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/AbstractRowsEventDataDeserializer.java index f0e43f2f..623f964b 100644 --- a/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/AbstractRowsEventDataDeserializer.java +++ b/src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/AbstractRowsEventDataDeserializer.java @@ -270,34 +270,14 @@ private java.util.Date deserializeDatetimeV2(int meta, ByteArrayInputStream inpu } private int getFractionalSeconds(int meta, ByteArrayInputStream inputStream) throws IOException { - int fractionalSecondsStorageSize = getFractionalSecondsStorageSize(meta); - if (fractionalSecondsStorageSize > 0) { - long fractionalSeconds = bigEndianLong(inputStream.read(fractionalSecondsStorageSize), 0, - fractionalSecondsStorageSize); - if (meta % 2 == 1) { - fractionalSeconds /= 10; - } - return (int) (fractionalSeconds / 1000); + int length = (meta + 1) / 2; + if (length > 0) { + long fraction = bigEndianLong(inputStream.read(length), 0, length); + return (int) (fraction / (0.1 * Math.pow(100, length - 1))); } return 0; } - private static int getFractionalSecondsStorageSize(int fsp) { - switch (fsp) { - case 1: - case 2: - return 1; - case 3: - case 4: - return 2; - case 5: - case 6: - return 3; - default: - return 0; - } - } - private static int extractBits(long value, int bitOffset, int numberOfBits, int payloadSize) { long result = value >> payloadSize - (bitOffset + numberOfBits); return (int) (result & ((1 << numberOfBits) - 1)); diff --git a/src/test/java/com/github/shyiko/mysql/binlog/BinaryLogClientIntegrationTest.java b/src/test/java/com/github/shyiko/mysql/binlog/BinaryLogClientIntegrationTest.java index fb859b0a..8c1c06fc 100644 --- a/src/test/java/com/github/shyiko/mysql/binlog/BinaryLogClientIntegrationTest.java +++ b/src/test/java/com/github/shyiko/mysql/binlog/BinaryLogClientIntegrationTest.java @@ -33,6 +33,7 @@ import com.github.shyiko.mysql.binlog.network.AuthenticationException; import com.github.shyiko.mysql.binlog.network.ServerException; import org.mockito.InOrder; +import org.testng.SkipException; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; @@ -49,6 +50,7 @@ import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import java.sql.SQLSyntaxErrorException; import java.sql.Statement; import java.util.BitSet; import java.util.Calendar; @@ -240,6 +242,36 @@ public void testDeserializationOfDifferentColumnTypes() throws Exception { assertEquals(writeAndCaptureRow("set('a','b','c')", "'a,c'"), new Serializable[]{5L}); } + @Test + public void testFSP() throws Exception { + try { + master.execute(new Callback() { + @Override + public void execute(Statement statement) throws SQLException { + statement.execute("create table fsp_check (column_ datetime(0))"); + } + }); + } catch (SQLSyntaxErrorException e) { + throw new SkipException("MySQL < 5.6.4+"); + } + assertEquals(writeAndCaptureRow("datetime(0)", "'1989-03-21 01:02:03.777777'"), new Serializable[]{ + new java.util.Date(generateTime(1989, 3, 21, 1, 2, 4, 0))}); + assertEquals(writeAndCaptureRow("datetime(1)", "'1989-03-21 01:02:03.777777'"), new Serializable[]{ + new java.util.Date(generateTime(1989, 3, 21, 1, 2, 3, 800))}); + assertEquals(writeAndCaptureRow("datetime(2)", "'1989-03-21 01:02:03.777777'"), new Serializable[]{ + new java.util.Date(generateTime(1989, 3, 21, 1, 2, 3, 780))}); + assertEquals(writeAndCaptureRow("datetime(3)", "'1989-03-21 01:02:03.777777'"), new Serializable[]{ + new java.util.Date(generateTime(1989, 3, 21, 1, 2, 3, 778))}); + assertEquals(writeAndCaptureRow("datetime(3)", "'1989-03-21 01:02:03.777'"), new Serializable[]{ + new java.util.Date(generateTime(1989, 3, 21, 1, 2, 3, 777))}); + assertEquals(writeAndCaptureRow("datetime(4)", "'1989-03-21 01:02:03.777777'"), new Serializable[]{ + new java.util.Date(generateTime(1989, 3, 21, 1, 2, 3, 777))}); + assertEquals(writeAndCaptureRow("datetime(5)", "'1989-03-21 01:02:03.777777'"), new Serializable[]{ + new java.util.Date(generateTime(1989, 3, 21, 1, 2, 3, 777))}); + assertEquals(writeAndCaptureRow("datetime(6)", "'1989-03-21 01:02:03.777777'"), new Serializable[]{ + new java.util.Date(generateTime(1989, 3, 21, 1, 2, 3, 777))}); + } + private BitSet bitSet(int... bitsToSetTrue) { BitSet result = new BitSet(bitsToSetTrue.length); for (int bit : bitsToSetTrue) {