From bfa56983a195cbd5011d23cb06005bd7386a46db Mon Sep 17 00:00:00 2001 From: volodya-lombrozo Date: Fri, 11 Mar 2022 18:45:19 +0300 Subject: [PATCH] Add rounding mode for irrational BigDecimal numbers --- .../client/data/ClickHouseDoubleValue.java | 41 ++++++++++++------- .../data/ClickHouseDoubleValueTest.java | 34 +++++++++++++++ 2 files changed, 61 insertions(+), 14 deletions(-) diff --git a/clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseDoubleValue.java b/clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseDoubleValue.java index fb9703408..7e03e4689 100644 --- a/clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseDoubleValue.java +++ b/clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseDoubleValue.java @@ -2,8 +2,10 @@ import java.math.BigDecimal; import java.math.BigInteger; +import java.math.RoundingMode; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; + import com.clickhouse.client.ClickHouseChecker; import com.clickhouse.client.ClickHouseValue; import com.clickhouse.client.ClickHouseValues; @@ -22,13 +24,15 @@ public static ClickHouseDoubleValue ofNull() { } /** - * Update given value to null or create a new instance if {@code ref} is null. - * + * Update given value to null or create a new instance if {@code ref} is + * null. + * * @param ref object to update, could be null * @return same object as {@code ref} or a new instance if it's null */ public static ClickHouseDoubleValue ofNull(ClickHouseValue ref) { - return ref instanceof ClickHouseDoubleValue ? ((ClickHouseDoubleValue) ref).set(true, 0D) + return ref instanceof ClickHouseDoubleValue ? + ((ClickHouseDoubleValue) ref).set(true, 0D) : new ClickHouseDoubleValue(true, 0D); } @@ -43,7 +47,8 @@ public static ClickHouseDoubleValue of(double value) { } /** - * Update value of the given object or create a new instance if {@code ref} is + * Update value of the given object or create a new instance if {@code + * ref} is * null. * * @param ref object to update, could be null @@ -51,7 +56,8 @@ public static ClickHouseDoubleValue of(double value) { * @return same object as {@code ref} or a new instance if it's null */ public static ClickHouseDoubleValue of(ClickHouseValue ref, double value) { - return ref instanceof ClickHouseDoubleValue ? ((ClickHouseDoubleValue) ref).set(false, value) + return ref instanceof ClickHouseDoubleValue ? + ((ClickHouseDoubleValue) ref).set(false, value) : new ClickHouseDoubleValue(false, value); } @@ -128,16 +134,16 @@ public BigDecimal asBigDecimal(int scale) { if (isNull) { return null; } - + final RoundingMode roundingMode = RoundingMode.HALF_UP; BigDecimal dec = BigDecimal.valueOf(value); if (value == 0D || isInfinity() || isNaN()) { - dec = dec.setScale(scale); + dec = dec.setScale(scale, roundingMode); } else { int diff = scale - dec.scale(); if (diff > 0) { dec = dec.divide(BigDecimal.TEN.pow(diff + 1)); } else if (diff < 0) { - dec = dec.setScale(scale); + dec = dec.setScale(scale, roundingMode); } } return dec; @@ -156,7 +162,8 @@ public String asString(int length, Charset charset) { String str = String.valueOf(value); if (length > 0) { - ClickHouseChecker.notWithDifferentLength(str.getBytes(charset == null ? StandardCharsets.UTF_8 : charset), + ClickHouseChecker.notWithDifferentLength(str.getBytes( + charset == null ? StandardCharsets.UTF_8 : charset), length); } @@ -225,27 +232,33 @@ public ClickHouseDoubleValue update(double value) { @Override public ClickHouseDoubleValue update(BigInteger value) { - return value == null ? resetToNullOrEmpty() : set(false, value.doubleValue()); + return value + == null ? resetToNullOrEmpty() : set(false, value.doubleValue()); } @Override public ClickHouseDoubleValue update(BigDecimal value) { - return value == null ? resetToNullOrEmpty() : set(false, value.doubleValue()); + return value + == null ? resetToNullOrEmpty() : set(false, value.doubleValue()); } @Override public ClickHouseDoubleValue update(Enum value) { - return value == null ? resetToNullOrEmpty() : set(false, value.ordinal()); + return value + == null ? resetToNullOrEmpty() : set(false, value.ordinal()); } @Override public ClickHouseDoubleValue update(String value) { - return value == null ? resetToNullOrEmpty() : set(false, Double.parseDouble(value)); + return value + == null ? resetToNullOrEmpty() : set(false, + Double.parseDouble(value)); } @Override public ClickHouseDoubleValue update(ClickHouseValue value) { - return value == null ? resetToNullOrEmpty() : set(false, value.asDouble()); + return value + == null ? resetToNullOrEmpty() : set(false, value.asDouble()); } @Override diff --git a/clickhouse-client/src/test/java/com/clickhouse/client/data/ClickHouseDoubleValueTest.java b/clickhouse-client/src/test/java/com/clickhouse/client/data/ClickHouseDoubleValueTest.java index 8609728e4..52c31d81d 100644 --- a/clickhouse-client/src/test/java/com/clickhouse/client/data/ClickHouseDoubleValueTest.java +++ b/clickhouse-client/src/test/java/com/clickhouse/client/data/ClickHouseDoubleValueTest.java @@ -10,6 +10,7 @@ import java.time.LocalTime; import java.time.ZoneOffset; import java.util.Arrays; +import java.util.Collections; import java.util.UUID; import org.testng.annotations.Test; import com.clickhouse.client.BaseClickHouseValueTest; @@ -250,5 +251,38 @@ public void testValue() throws Exception { buildMap(new Object[] { 1 }, new Double[] { -1D }), // typed Map Arrays.asList(Double.valueOf(-1D)) // Tuple ); + + checkValue(ClickHouseDoubleValue.of(4D/3), false, // isInfinity + false, // isNan + false, // isNull + true, // boolean + (byte) 1, // byte + (short) 1, // short + 1, // int + 1L, // long + 1.3333334F, // float + 1.3333333333333333D, // double + BigDecimal.valueOf(1L), // BigDecimal + BigDecimal.valueOf(1333,3), // BigDecimal + BigInteger.ONE, // BigInteger + ClickHouseDataType.values()[1].name(), // Enum + 1.3333333333333333D, // Object + LocalDate.ofEpochDay(1L), // Date + LocalDateTime.ofEpochSecond(1L, 0, ZoneOffset.UTC), // DateTime + LocalDateTime.ofEpochSecond(1L, 333333333, ZoneOffset.UTC), // DateTime(9) + Inet4Address.getAllByName("0.0.0.1")[0], // Inet4Address + Inet6Address.getAllByName("0:0:0:0:0:0:0:1")[0], // Inet6Address + "1.3333333333333333", // String + "1.3333333333333333", // SQL Expression + LocalTime.ofSecondOfDay(1), // Time + UUID.fromString("00000000-0000-0000-0000-000000000001"), // UUID + Object.class, // Key class + Double.class, // Value class + new Object[] { 1.3333333333333333D }, // Array + new Double[] { 1.3333333333333333D }, // typed Array + buildMap(new Object[] { 1 }, new Object[] { 1.3333333333333333D }), // Map + buildMap(new Object[] { 1 }, new Double[] { 1.3333333333333333D }), // typed Map + Collections.singletonList(1.3333333333333333D) // Tuple + ); } }