From 169f128eb478e24f6e706486dd5dd2019f223619 Mon Sep 17 00:00:00 2001 From: Sharang Gupta Date: Wed, 28 Oct 2026 23:48:45 +0000 Subject: [PATCH] Fix encoding of negative fractional TIME values Duration.getSeconds() is floored, so borrowing a second for the fraction wrote second = -1 whenever the floored value was a whole minute, and MySQL stored -59.5 seconds as zero. Signed-off-by: Sharang Gupta Assisted-by: Anthropic Claude (claude-opus-5-5) --- .../impl/datatype/DataTypeCodec.java | 18 ++++++------------ .../data/DateTimeBinaryCodecTest.java | 5 +++++ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/datatype/DataTypeCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/datatype/DataTypeCodec.java index d153e4cd5..543e3f4db 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/datatype/DataTypeCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/datatype/DataTypeCodec.java @@ -387,17 +387,17 @@ private static void binaryEncodeTime(LocalTime value, ByteBuf buffer) { } private static void binaryEncodeTime(Duration value, ByteBuf buffer) { - long secondsOfDuration = value.getSeconds(); - int nanosOfDuration = value.getNano(); - if (secondsOfDuration == 0 && nanosOfDuration == 0) { + if (value.isZero()) { buffer.writeByte(0); return; } byte isNegative = 0; - if (secondsOfDuration < 0) { + if (value.isNegative()) { isNegative = 1; - secondsOfDuration = -secondsOfDuration; + value = value.negated(); } + long secondsOfDuration = value.getSeconds(); + int nanosOfDuration = value.getNano(); int days = (int) (secondsOfDuration / 86400); int secondsOfADay = (int) (secondsOfDuration % 86400); @@ -415,13 +415,7 @@ private static void binaryEncodeTime(Duration value, ByteBuf buffer) { return; } - int microSecond; - if (isNegative == 1 && nanosOfDuration > 0) { - second = second - 1; - microSecond = (1000_000_000 - nanosOfDuration) / 1000; - } else { - microSecond = nanosOfDuration / 1000; - } + int microSecond = nanosOfDuration / 1000; buffer.writeByte(12); buffer.writeByte(isNegative); diff --git a/vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/data/DateTimeBinaryCodecTest.java b/vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/data/DateTimeBinaryCodecTest.java index 0d17f3bc2..9f01927ef 100644 --- a/vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/data/DateTimeBinaryCodecTest.java +++ b/vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/data/DateTimeBinaryCodecTest.java @@ -82,6 +82,11 @@ public void testEncodeFractionalSecondsPart(TestContext ctx) { testEncodeTime(ctx, Duration.ofHours(11).plusMinutes(12).plusNanos(123456000), Duration.ofHours(11).plusMinutes(12).plusNanos(123456000)); } + @Test + public void testEncodeNegativeFractionalSecondsPart(TestContext ctx) { + testEncodeTime(ctx, Duration.ofSeconds(-59).minusMillis(500), Duration.ofSeconds(-59).minusMillis(500)); + } + @Test public void testEncodeTimeFromLocalTimeWithFractionalSecondsPart(TestContext ctx) { testEncodeTime(ctx, LocalTime.of(11, 12, 0, 123456000), Duration.ofHours(11).plusMinutes(12).plusNanos(123456000), LocalTime.of(11, 12, 0, 123456000));