osheroff / mysql-binlog-connector-java

MySQL Binary Log connector
680 stars 167 forks source link

Incorrect handling of negative TIME values #154

Open fivetran-nghiale opened 2 months ago

fivetran-nghiale commented 2 months ago

Reproduction

Run test in BinaryLogClientIntegrationTest

  @Test
  public void testDeserializationOfTIME() throws Exception {
      assertEquals(writeAndCaptureRow("time", "'-00:00:01'"), new Serializable[]{
          generateTime(1969, 12, 31, 23, 59, 59, 0)});
  }

Test fails with

java.lang.AssertionError: Lists differ at element [0]: -1000 != 3686643000
Expected :-1000
Actual   :3686643000

where 3686643000 is equivalent to Feb 12 1970 16:04:03.000

fivetran-nghiale commented 2 months ago

Tagging @Naros for awareness here since I know your team at Debezium has forked from the Osheroff client. Are you folks aware of this bug?

Naros commented 1 month ago

Thanks @fivetran-nghiale, is this specific to a certain version of MySQL or MariaDB?

Naros commented 1 month ago

I tested with MySQL 8.2 and MariaDB 11.4.3 with Debezium 3, and in both cases, the TIME field was emitted in Debezium as -1000000L, as expected. I haven't looked at the BinlogClient test case, but maybe the issue is just the tests logic?

fivetran-nghiale commented 1 month ago

Thanks for replying here!

I was running the integration tests from the repository which appears to spin up a MySQL 5.7.17 server according to the output logs but haven't tried other versions.

It is possible that I am missing something but I noticed that the call to asUnixTime for deserializing TIMEV2 is hardcoded to January 1st, 1970 which is the reason why I created this issue in the first place as I didn't think it was possible to generate negative long values from the method return (if dates prior to Unix epoch can be considered negative timestamps).

Something else I noticed is that the sign bit is never used as well from the ByteArrayInputStream inputStream in the deserializeTimeV2 method.