Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,12 @@ public static BigDecimal toBigDecimal(Object value) {
return (BigDecimal) value;
} else if (value instanceof BigInteger) {
return new BigDecimal((BigInteger) value);
} else if (value instanceof Number) {
} else if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
return BigDecimal.valueOf(((Number) value).longValue());
} else if (value instanceof Float || value instanceof Double) {
return BigDecimal.valueOf(((Number) value).doubleValue());
} else if (value instanceof Number) {
return new BigDecimal(value.toString());
} else if (value instanceof String) {
return new BigDecimal((String) value);
} else if (value instanceof Boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import static org.objectweb.asm.Opcodes.RETURN;

Comment thread
chernser marked this conversation as resolved.
@SuppressWarnings("deprecation")
public class SerializerUtils {

public static void serializeData(OutputStream stream, Object value, ClickHouseColumn column) throws IOException {
Expand Down Expand Up @@ -505,10 +506,10 @@ private static void serializePrimitiveData(OutputStream stream, Object value, Cl
BinaryStreamUtils.writeInt64(stream, convertToLong(value));
break;
case Int128:
BinaryStreamUtils.writeInt128(stream, convertToBigInteger(value));
BinaryStreamUtils.writeInt128(stream, NumberConverter.toBigInteger(value));
break;
case Int256:
BinaryStreamUtils.writeInt256(stream, convertToBigInteger(value));
BinaryStreamUtils.writeInt256(stream, NumberConverter.toBigInteger(value));
break;
case UInt8:
BinaryStreamUtils.writeUnsignedInt8(stream, convertToInteger(value));
Expand All @@ -523,10 +524,10 @@ private static void serializePrimitiveData(OutputStream stream, Object value, Cl
BinaryStreamUtils.writeUnsignedInt64(stream, convertToLong(value));
Comment thread
chernser marked this conversation as resolved.
Outdated
break;
case UInt128:
BinaryStreamUtils.writeUnsignedInt128(stream, convertToBigInteger(value));
BinaryStreamUtils.writeUnsignedInt128(stream, NumberConverter.toBigInteger(value));
break;
case UInt256:
BinaryStreamUtils.writeUnsignedInt256(stream, convertToBigInteger(value));
BinaryStreamUtils.writeUnsignedInt256(stream, NumberConverter.toBigInteger(value));
break;
case Float32:
BinaryStreamUtils.writeFloat32(stream, (float) value);
Expand All @@ -539,7 +540,7 @@ private static void serializePrimitiveData(OutputStream stream, Object value, Cl
case Decimal64:
case Decimal128:
case Decimal256:
BinaryStreamUtils.writeDecimal(stream, convertToBigDecimal(value), column.getPrecision(), column.getScale());
BinaryStreamUtils.writeDecimal(stream, NumberConverter.toBigDecimal(value), column.getPrecision(), column.getScale());
break;
case Bool:
BinaryStreamUtils.writeBoolean(stream, (Boolean) value);
Expand Down Expand Up @@ -765,32 +766,6 @@ public static Long convertToLong(Object value) {
}
}

public static BigInteger convertToBigInteger(Object value) {
if (value instanceof BigInteger) {
return (BigInteger) value;
} else if (value instanceof Number) {
return BigInteger.valueOf(((Number) value).longValue());
} else if (value instanceof String) {
return new BigInteger((String) value);
} else {
throw new IllegalArgumentException("Cannot convert " + value + " to BigInteger");
}
}

public static BigDecimal convertToBigDecimal(Object value) {
if (value instanceof BigDecimal) {
return (BigDecimal) value;
} else if (value instanceof BigInteger) {
return new BigDecimal((BigInteger) value);
} else if (value instanceof Number) {
return BigDecimal.valueOf(((Number) value).doubleValue());
} else if (value instanceof String) {
return new BigDecimal((String) value);
} else {
throw new IllegalArgumentException("Cannot convert " + value + " to BigDecimal");
}
}

public static String convertToString(Object value) {
return java.lang.String.valueOf(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Collections;
Expand Down Expand Up @@ -210,7 +209,13 @@ public BigInteger convertNumberToBigInteger(Object value) {
}

public BigDecimal convertNumberToBigDecimal(Object value) {
return BigDecimal.valueOf(((Number) value).doubleValue());
Number number = (Number) value;
Comment thread
chernser marked this conversation as resolved.
Outdated
if (number instanceof Byte || number instanceof Short || number instanceof Integer || number instanceof Long) {
return BigDecimal.valueOf(number.longValue());
} else if (number instanceof Float || number instanceof Double) {
return BigDecimal.valueOf(number.doubleValue());
}
return new BigDecimal(number.toString());
}

// Date & Time converters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.TimeZone;
import java.util.function.Consumer;

@SuppressWarnings("deprecation")
public class ClickHouseBinaryFormatReaderTest {

@Test
Expand Down Expand Up @@ -83,6 +84,66 @@ public void testReadingNumbers() throws IOException {
}
}

@Test
public void testGetBigDecimalForIntegerWidths8To256() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();

String[] names = new String[] {
"i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "i128", "u128", "i256", "u256"
};
String[] types = new String[] {
"Int8", "UInt8", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64",
"Int128", "UInt128", "Int256", "UInt256"
};

BinaryStreamUtils.writeVarInt(out, names.length);
for (String name : names) {
BinaryStreamUtils.writeString(out, name);
}
for (String type : types) {
BinaryStreamUtils.writeString(out, type);
}

BigInteger u64 = new BigInteger("18446744073709551615");
BigInteger i128 = new BigInteger("-170141183460469231731687303715884105728");
BigInteger u128 = new BigInteger("340282366920938463463374607431768211455");
BigInteger i256 = new BigInteger("-57896044618658097711785492504343953926634992332820282019728792003956564819968");
BigInteger u256 = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935");

BinaryStreamUtils.writeInt8(out, -128);
BinaryStreamUtils.writeUnsignedInt8(out, 255);
BinaryStreamUtils.writeInt16(out, -32768);
BinaryStreamUtils.writeUnsignedInt16(out, 65535);
BinaryStreamUtils.writeInt32(out, Integer.MIN_VALUE);
BinaryStreamUtils.writeUnsignedInt32(out, 4294967295L);
BinaryStreamUtils.writeInt64(out, Long.MAX_VALUE);
BinaryStreamUtils.writeUnsignedInt64(out, u64);
BinaryStreamUtils.writeInt128(out, i128);
BinaryStreamUtils.writeUnsignedInt128(out, u128);
BinaryStreamUtils.writeInt256(out, i256);
BinaryStreamUtils.writeUnsignedInt256(out, u256);

InputStream in = new ByteArrayInputStream(out.toByteArray());
QuerySettings querySettings = new QuerySettings().setUseTimeZone(TimeZone.getTimeZone("UTC").toZoneId().getId());
RowBinaryWithNamesAndTypesFormatReader reader =
new RowBinaryWithNamesAndTypesFormatReader(in, querySettings, new BinaryStreamReader.CachingByteBufferAllocator());

reader.next();

Assert.assertEquals(reader.getBigDecimal("i8"), BigDecimal.valueOf(-128));
Assert.assertEquals(reader.getBigDecimal("u8"), BigDecimal.valueOf(255));
Assert.assertEquals(reader.getBigDecimal("i16"), BigDecimal.valueOf(-32768));
Assert.assertEquals(reader.getBigDecimal("u16"), BigDecimal.valueOf(65535));
Assert.assertEquals(reader.getBigDecimal("i32"), BigDecimal.valueOf(Integer.MIN_VALUE));
Assert.assertEquals(reader.getBigDecimal("u32"), BigDecimal.valueOf(4294967295L));
Assert.assertEquals(reader.getBigDecimal("i64"), BigDecimal.valueOf(Long.MAX_VALUE));
Assert.assertEquals(reader.getBigDecimal("u64"), new BigDecimal(u64));
Assert.assertEquals(reader.getBigDecimal("i128"), new BigDecimal(i128));
Assert.assertEquals(reader.getBigDecimal("u128"), new BigDecimal(u128));
Assert.assertEquals(reader.getBigDecimal("i256"), new BigDecimal(i256));
Assert.assertEquals(reader.getBigDecimal("u256"), new BigDecimal(u256));
}

@Test
public void testReadingNumbersWithOverflow() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Expand Down
Loading