From 50f16415a066676d2da0c5da9edadddbe01d6146 Mon Sep 17 00:00:00 2001 From: Sharang Gupta Date: Thu, 29 Oct 2026 00:11:51 +0000 Subject: [PATCH] Encode negative-scale BigDecimal values correctly The scale byte was clamped to zero but the unscaled value was not multiplied back, so 1.5E+3 (1500 after stripTrailingZeros) was sent as 15. Signed-off-by: Sharang Gupta Assisted-by: Anthropic Claude (claude-opus-5-5) --- .../java/io/vertx/mssqlclient/impl/codec/DataType.java | 5 ++++- .../data/MSSQLPreparedQueryNotNullableDataTypeTest.java | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/DataType.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/DataType.java index 19fd76fb4b..e47a943ba9 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/DataType.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/DataType.java @@ -413,11 +413,14 @@ public String paramDefinition(Object value) { @Override public void encodeParam(ByteBuf byteBuf, String name, boolean out, Object value) { BigDecimal bigDecimal = (BigDecimal) value; + if (bigDecimal.scale() < 0) { + bigDecimal = bigDecimal.setScale(0); + } writeParamDescription(byteBuf, name, out, id); writeParamSize(byteBuf, 17, 38); int sign = bigDecimal.signum() < 0 ? 0 : 1; byte[] bytes = (sign == 0 ? bigDecimal.negate() : bigDecimal).unscaledValue().toByteArray(); - byteBuf.writeByte(Math.max(0, bigDecimal.scale())); + byteBuf.writeByte(bigDecimal.scale()); byteBuf.writeByte(1 + bytes.length); byteBuf.writeByte(sign); for (int i = bytes.length - 1; i >= 0; i--) byteBuf.writeByte(bytes[i]); diff --git a/vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/data/MSSQLPreparedQueryNotNullableDataTypeTest.java b/vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/data/MSSQLPreparedQueryNotNullableDataTypeTest.java index 0a4c28adc3..7ca597ade6 100644 --- a/vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/data/MSSQLPreparedQueryNotNullableDataTypeTest.java +++ b/vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/data/MSSQLPreparedQueryNotNullableDataTypeTest.java @@ -74,6 +74,13 @@ public void testEncodeDecimal(TestContext ctx) { testEncodeNumber(ctx, "test_decimal", new BigDecimal("123456789")); } + @Test + public void testEncodeDecimalWithNegativeScale(TestContext ctx) { + testPreparedQueryEncodeGeneric(ctx, "not_nullable_datatype", "test_decimal", new BigDecimal("1500").stripTrailingZeros(), row -> { + checkNumber(row, "test_decimal", new BigDecimal("1500")); + }); + } + @Test public void testEncodeBit(TestContext ctx) { testPreparedQueryEncodeGeneric(ctx, "not_nullable_datatype", "test_boolean", false, row -> {