Skip to content

Commit 6bc12ab

Browse files
committed
implemented convertion from boolean, to boolean. Added tests
1 parent eb0bfaf commit 6bc12ab

File tree

4 files changed

+170
-49
lines changed

4 files changed

+170
-49
lines changed

client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/AbstractBinaryFormatReader.java

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ protected void setSchema(TableSchema schema) {
231231
for (int i = 0; i < columns.length; i++) {
232232
ClickHouseColumn column = columns[i];
233233

234-
Map<NumberType, Function<Number, ?>> converters = new HashMap<>();
234+
Map<NumberType, Function<Object, ?>> converters = new HashMap<>();
235235
switch (column.getDataType()) {
236236
case Int8:
237237
case Int16:
@@ -300,9 +300,9 @@ public String getString(int index) {
300300

301301
private <T> T readNumberValue(String colName, NumberType targetType) {
302302
int colIndex = schema.nameToIndex(colName);
303-
Function<Number, Number> converter = (Function<Number, Number>) convertions[colIndex].get(targetType);
303+
Function<Object, Object> converter = (Function<Object, Object>) convertions[colIndex].get(targetType);
304304
if (converter != null) {
305-
Number value = readValue(colName);
305+
Object value = readValue(colName);
306306
if (value == null) {
307307
throw new NullValueException("Column " + colName + " has null value and it cannot be cast to " +
308308
targetType.getTypeName());
@@ -466,17 +466,25 @@ public ClickHouseGeoMultiPolygonValue getGeoMultiPolygon(String colName) {
466466

467467
@Override
468468
public <T> List<T> getList(String colName) {
469-
BinaryStreamReader.ArrayValue array = readValue(colName);
470-
return array.asList();
469+
try {
470+
BinaryStreamReader.ArrayValue array = readValue(colName);
471+
return array.asList();
472+
} catch (ClassCastException e) {
473+
throw new ClientException("Column is not of array type", e);
474+
}
471475
}
472476

473477

474478
private <T> T getPrimitiveArray(String colName) {
475-
BinaryStreamReader.ArrayValue array = readValue(colName);
476-
if (array.itemType.isPrimitive()) {
477-
return (T) array.array;
478-
} else {
479-
throw new ClientException("Array is not of primitive type");
479+
try {
480+
BinaryStreamReader.ArrayValue array = readValue(colName);
481+
if (array.itemType.isPrimitive()) {
482+
return (T) array.array;
483+
} else {
484+
throw new ClientException("Array is not of primitive type");
485+
}
486+
} catch (ClassCastException e) {
487+
throw new ClientException("Column is not of array type", e);
480488
}
481489
}
482490

client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/SerializerUtils.java

Lines changed: 104 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -585,73 +585,140 @@ public static void writeBoolean(OutputStream output, boolean value) throws IOExc
585585

586586
public static class NumberConverter {
587587

588-
public static byte toByte(Number value) {
589-
if (value.byteValue() == value.shortValue()) {
590-
return value.byteValue();
588+
public static byte toByte(Object value) {
589+
if (value instanceof Number) {
590+
Number number = (Number) value;
591+
if (number.byteValue() == number.shortValue()) {
592+
return number.byteValue();
593+
} else {
594+
throw new ArithmeticException("integer overflow: " + value + " cannot be presented as byte");
595+
}
596+
} else if (value instanceof Boolean) {
597+
return (byte) ((Boolean) value ? 1 : 0);
598+
} else if (value instanceof String) {
599+
return Byte.parseByte(value.toString());
591600
} else {
592-
throw new ArithmeticException("integer overflow: " + value + " cannot be presented as byte");
601+
throw new IllegalArgumentException("Cannot convert " + value + " to byte value");
593602
}
594603
}
595604

596-
public static short toShort(Number value) {
597-
if (value.shortValue() == value.intValue()) {
598-
return value.shortValue();
605+
public static short toShort(Object value) {
606+
if (value instanceof Number) {
607+
Number number = (Number) value;
608+
if (number.shortValue() == number.intValue()) {
609+
return number.shortValue();
610+
} else {
611+
throw new ArithmeticException("integer overflow: " + value + " cannot be presented as short");
612+
}
613+
} else if (value instanceof Boolean) {
614+
return (short) ((Boolean) value ? 1 : 0);
615+
} else if ( value instanceof String) {
616+
return Short.parseShort(value.toString());
599617
} else {
600-
throw new ArithmeticException("integer overflow: " + value + " cannot be presented as short");
618+
throw new IllegalArgumentException("Cannot convert " + value + " to short value");
601619
}
602620
}
603621

604-
public static int toInt(Number value) {
605-
if (value.intValue() == value.longValue()) {
606-
return value.intValue();
622+
public static int toInt(Object value) {
623+
if (value instanceof Number) {
624+
Number number = (Number) value;
625+
if (number.intValue() == number.longValue()) {
626+
return number.intValue();
627+
} else {
628+
throw new ArithmeticException("integer overflow: " + value + " cannot be presented as int");
629+
}
630+
} else if (value instanceof Boolean) {
631+
return (Boolean) value ? 1 : 0;
632+
} else if (value instanceof String) {
633+
return Integer.parseInt((String) value);
607634
} else {
608-
throw new ArithmeticException("integer overflow: " + value + " cannot be presented as int");
635+
throw new IllegalArgumentException("Cannot convert " + value + " to int value");
609636
}
610637
}
611638

612-
public static long toLong(Number value) {
613-
if (value.longValue() == value.doubleValue()) {
614-
return value.longValue();
639+
public static long toLong(Object value) {
640+
if (value instanceof Number) {
641+
Number number = (Number) value;
642+
if (number.longValue() == number.doubleValue()) {
643+
return number.longValue();
644+
} else {
645+
throw new ArithmeticException("integer overflow: " + value + " cannot be presented as long");
646+
}
647+
} else if (value instanceof Boolean) {
648+
return (Boolean) value ? 1 : 0;
649+
} else if (value instanceof String) {
650+
return Long.parseLong((String) value);
615651
} else {
616-
throw new ArithmeticException("integer overflow: " + value + " cannot be presented as long");
652+
throw new IllegalArgumentException("Cannot convert " + value + " to long value");
617653
}
618654
}
619655

620-
621-
public static BigInteger toBigInteger(Number value) {
622-
return value instanceof BigInteger ? (BigInteger) value : BigInteger.valueOf(value.longValue());
623-
}
624-
625-
public static BigInteger toBigInteger(String value) {
626-
return new BigInteger(value);
656+
public static BigInteger toBigInteger(Object value) {
657+
if (value instanceof BigInteger) {
658+
return (BigInteger) value;
659+
} else if (value instanceof Number) {
660+
return BigInteger.valueOf(((Number) value).longValue());
661+
} else if (value instanceof Boolean) {
662+
return (Boolean) value ? BigInteger.ONE : BigInteger.ZERO;
663+
} else if (value instanceof String) {
664+
return new BigInteger((String) value);
665+
} else {
666+
throw new IllegalArgumentException("Cannot convert " + value + " to BigInteger value");
667+
}
627668
}
628669

629-
public static float toFloat(Number value) {
670+
public static float toFloat(Object value) {
630671
if (value instanceof Float) {
631672
return (Float) value;
632-
} else if (value.floatValue() == value.doubleValue()) {
633-
return value.floatValue();
673+
} else if (value instanceof Number) {
674+
Number number = (Number) value;
675+
if (number.floatValue() == number.doubleValue()) {
676+
return number.floatValue();
677+
} else {
678+
throw new ArithmeticException("float overflow: " + value + " cannot be presented as float");
679+
}
680+
} else if (value instanceof Boolean) {
681+
return (Boolean) value ? 1.0f : 0.0f;
682+
} else if (value instanceof String ) {
683+
return Float.parseFloat((String) value);
634684
} else {
635-
throw new ArithmeticException("float overflow: " + value + " cannot be presented as float");
685+
throw new IllegalArgumentException("Cannot convert " + value + " to float value");
636686
}
637687
}
638688

639-
public static double toDouble(Number value) {
689+
public static double toDouble(Object value) {
640690
if (value instanceof Double) {
641691
return (Double) value;
642-
} else if (value.doubleValue() == value.floatValue()) {
643-
return value.doubleValue();
692+
} else if (value instanceof Number) {
693+
Number number = (Number) value;
694+
if (number.doubleValue() == number.floatValue()) {
695+
return number.doubleValue();
696+
} else {
697+
throw new ArithmeticException("double overflow: " + value + " cannot be presented as double");
698+
}
699+
} else if (value instanceof Boolean) {
700+
return (Boolean) value ? 1.0 : 0.0;
701+
} else if (value instanceof String) {
702+
return Double.parseDouble((String) value);
644703
} else {
645-
throw new ArithmeticException("double overflow: " + value + " cannot be presented as double");
704+
throw new IllegalArgumentException("Cannot convert " + value + " to double value");
646705
}
647706
}
648707

649-
public static BigDecimal toBigDecimal(Number value) {
650-
return value instanceof BigDecimal ? (BigDecimal) value : BigDecimal.valueOf(value.doubleValue());
651-
}
652-
653-
public static BigDecimal toBigDecimal(String value) {
654-
return new BigDecimal(value);
708+
public static BigDecimal toBigDecimal(Object value) {
709+
if (value instanceof BigDecimal) {
710+
return (BigDecimal) value;
711+
} else if (value instanceof BigInteger) {
712+
return new BigDecimal((BigInteger) value);
713+
} else if (value instanceof Number) {
714+
return BigDecimal.valueOf(((Number) value).doubleValue());
715+
} else if (value instanceof String) {
716+
return new BigDecimal((String) value);
717+
} else if (value instanceof Boolean) {
718+
return (Boolean) value ? BigDecimal.ONE : BigDecimal.ZERO;
719+
} else {
720+
throw new IllegalArgumentException("Cannot convert " + value + " to BigDecimal value");
721+
}
655722
}
656723
}
657724
}

client-v2/src/test/java/com/clickhouse/client/api/data_formats/ClickHouseBinaryFormatReaderTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,52 @@ public void testReadingNumbersWithOverflow() throws IOException {
140140
Arrays.stream("h,i,j,k,l,n,p,q,r".split(",")).forEach(floatConsumer);
141141
Arrays.stream("h,i,j,k,l,p,q,r".split(",")).forEach(doubleConsumer);
142142
}
143+
144+
@Test
145+
public void testReadingAsBoolean() throws Exception {
146+
ByteArrayOutputStream out = new ByteArrayOutputStream();
147+
148+
String[] names = new String[]{ "a", "b"};
149+
String[] types = new String[]{"Bool", "Bool"};
150+
151+
BinaryStreamUtils.writeVarInt(out, names.length);
152+
for (String name : names) {
153+
BinaryStreamUtils.writeString(out, name);
154+
}
155+
for (String type : types) {
156+
BinaryStreamUtils.writeString(out, type);
157+
}
158+
159+
160+
BinaryStreamUtils.writeBoolean(out, true);
161+
BinaryStreamUtils.writeBoolean(out, false);
162+
163+
InputStream in = new ByteArrayInputStream(out.toByteArray());
164+
QuerySettings querySettings = new QuerySettings().setUseTimeZone(TimeZone.getTimeZone("UTC").toZoneId().getId());
165+
RowBinaryWithNamesAndTypesFormatReader reader =
166+
new RowBinaryWithNamesAndTypesFormatReader(in, querySettings, new BinaryStreamReader.CachingByteBufferAllocator());
167+
168+
reader.next();
169+
170+
Assert.assertEquals(reader.getBoolean("a"), Boolean.TRUE);
171+
Assert.assertEquals(reader.getBoolean("b"), Boolean.FALSE);
172+
Assert.assertEquals(reader.getByte("a"), (byte) 1);
173+
Assert.assertEquals(reader.getByte("b"), (byte) 0);
174+
Assert.assertEquals(reader.getShort("a"), (short) 1);
175+
Assert.assertEquals(reader.getShort("b"), (short) 0);
176+
Assert.assertEquals(reader.getInteger("a"), 1);
177+
Assert.assertEquals(reader.getInteger("b"), 0);
178+
Assert.assertEquals(reader.getLong("a"), 1);
179+
Assert.assertEquals(reader.getLong("b"), 0);
180+
Assert.assertEquals(reader.getFloat("a"), 1.0f);
181+
Assert.assertEquals(reader.getFloat("b"), 0.0f);
182+
Assert.assertEquals(reader.getDouble("a"), 1.0d);
183+
Assert.assertEquals(reader.getDouble("b"), 0.0d);
184+
Assert.assertEquals(reader.getBigInteger("a"), BigInteger.ONE);
185+
Assert.assertEquals(reader.getBigInteger("b"), BigInteger.ZERO);
186+
Assert.assertEquals(reader.getBigDecimal("a"), BigDecimal.ONE);
187+
Assert.assertEquals(reader.getBigDecimal("b"), BigDecimal.ZERO);
188+
Assert.assertEquals(reader.getString("a"), "true");
189+
Assert.assertEquals(reader.getString("b"), "false");
190+
}
143191
}

client-v2/src/test/java/com/clickhouse/client/query/QueryTests.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,10 @@ public void testBigUnsignedInt() throws Exception {
189189
final BigInteger expected256 = BigInteger.valueOf(2).pow(256).subtract(BigInteger.ONE).subtract(BigInteger.ONE);
190190

191191
String sqlQuery = "SELECT toUInt128('" + expected128 + "') as i128, toUInt256('" + expected256 + "') as i256";
192-
System.out.println(sqlQuery);
193192
Records records = client.queryRecords(sqlQuery).get(3, TimeUnit.SECONDS);
194193

195194
GenericRecord firstRecord = records.iterator().next();
196195

197-
System.out.println(firstRecord.getBigInteger("i128"));
198196
Assert.assertEquals(firstRecord.getBigInteger("i128"), expected128);
199197
Assert.assertEquals(firstRecord.getBigInteger("i256"), expected256);
200198
}

0 commit comments

Comments
 (0)