From 57d8d7622990ff013045bab0b91ebdc78e943e17 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Wed, 6 Jul 2022 16:22:57 -0400 Subject: [PATCH 1/2] Fixes number cast exception when Boolean[] is used in ClickHouseArrayValue --- .../data/array/ClickHouseByteArrayValue.java | 6 ++++- .../ClickHouseRowBinaryProcessorTest.java | 26 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseByteArrayValue.java b/clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseByteArrayValue.java index 22c851f50..45b357197 100644 --- a/clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseByteArrayValue.java +++ b/clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseByteArrayValue.java @@ -460,7 +460,11 @@ public ClickHouseByteArrayValue update(Object[] value) { byte[] values = new byte[len]; for (int i = 0; i < len; i++) { Object o = value[i]; - values[i] = o == null ? 0 : ((Number) o).byteValue(); + if (value[i] instanceof Boolean) { + values[i] = (Boolean) o ? (byte) 1 : (byte) 0; + } else { + values[i] = o == null ? 0 : ((Number) o).byteValue(); + } } set(values); } diff --git a/clickhouse-client/src/test/java/com/clickhouse/client/data/ClickHouseRowBinaryProcessorTest.java b/clickhouse-client/src/test/java/com/clickhouse/client/data/ClickHouseRowBinaryProcessorTest.java index cd21e82af..a111f7e74 100644 --- a/clickhouse-client/src/test/java/com/clickhouse/client/data/ClickHouseRowBinaryProcessorTest.java +++ b/clickhouse-client/src/test/java/com/clickhouse/client/data/ClickHouseRowBinaryProcessorTest.java @@ -175,6 +175,32 @@ public void testSerializeArray() throws IOException { 0x63, 0, 2, 1, 0)); } + @Test(groups = { "unit" }) + public void testSerializeBoolean() throws IOException { + ClickHouseConfig config = new ClickHouseConfig(); + + ClickHouseValue value = ClickHouseArrayValue.of(new Boolean[][] { new Boolean[] { true, false } }); + ByteArrayOutputStream bas = new ByteArrayOutputStream(); + ClickHouseOutputStream out = ClickHouseOutputStream.of(bas); + ClickHouseRowBinaryProcessor.getMappedFunctions().serialize(value, config, + ClickHouseColumn.of("a", "Array(Array(Boolean))"), out); + out.flush(); + Assert.assertEquals(bas.toByteArray(), BinaryStreamUtilsTest.generateBytes(1, 2, 1, 0)); + + boolean[] nativeBoolArray = new boolean[3]; + nativeBoolArray[0] = true; + nativeBoolArray[1] = false; + nativeBoolArray[2] = true; + + ClickHouseValue value2 = ClickHouseArrayValue.of(new boolean[][]{nativeBoolArray}); + ByteArrayOutputStream bas2 = new ByteArrayOutputStream(); + ClickHouseOutputStream out2 = ClickHouseOutputStream.of(bas2); + ClickHouseRowBinaryProcessor.getMappedFunctions().serialize(value2, config, + ClickHouseColumn.of("a", "Array(Array(boolean))"), out2); + out2.flush(); + Assert.assertEquals(bas2.toByteArray(), BinaryStreamUtilsTest.generateBytes(1, 3, 1, 0, 1)); + } + @Test(groups = { "unit" }) public void testDeserializeMap() throws IOException { ClickHouseConfig config = new ClickHouseConfig(); From 8cc603314be8ef43191a1b325ac488a334e16506 Mon Sep 17 00:00:00 2001 From: Zhichun Wu Date: Fri, 8 Jul 2022 18:53:13 +0800 Subject: [PATCH 2/2] Convert byte[] to Boolean[] and more tests --- .../data/array/ClickHouseByteArrayValue.java | 28 +++++++++++++------ .../array/ClickHouseByteArrayValueTest.java | 26 +++++++++++++++++ 2 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 clickhouse-client/src/test/java/com/clickhouse/client/data/array/ClickHouseByteArrayValueTest.java diff --git a/clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseByteArrayValue.java b/clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseByteArrayValue.java index 45b357197..43c891b27 100644 --- a/clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseByteArrayValue.java +++ b/clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseByteArrayValue.java @@ -91,11 +91,19 @@ public Object[] asArray() { public E[] asArray(Class clazz) { byte[] v = getValue(); int len = v.length; - E[] array = ClickHouseValues.createObjectArray(clazz, len, 1); - for (int i = 0; i < len; i++) { - array[i] = clazz.cast(v[i]); + if (clazz == Boolean.class) { + Boolean[] array = new Boolean[len]; + for (int i = 0; i < len; i++) { + array[i] = v[i] == (byte) 1 ? Boolean.TRUE : Boolean.FALSE; + } + return (E[]) array; + } else { + E[] array = ClickHouseValues.createObjectArray(clazz, len, 1); + for (int i = 0; i < len; i++) { + array[i] = clazz.cast(v[i]); + } + return array; } - return array; } @Override @@ -456,15 +464,17 @@ public ClickHouseByteArrayValue update(Object[] value) { int len = value == null ? 0 : value.length; if (len == 0) { return resetToNullOrEmpty(); + } else if (value instanceof Boolean[]) { + byte[] values = new byte[len]; + for (int i = 0; i < len; i++) { + values[i] = Boolean.TRUE.equals(value[i]) ? (byte) 1 : (byte) 0; + } + set(values); } else { byte[] values = new byte[len]; for (int i = 0; i < len; i++) { Object o = value[i]; - if (value[i] instanceof Boolean) { - values[i] = (Boolean) o ? (byte) 1 : (byte) 0; - } else { - values[i] = o == null ? 0 : ((Number) o).byteValue(); - } + values[i] = o == null ? 0 : ((Number) o).byteValue(); } set(values); } diff --git a/clickhouse-client/src/test/java/com/clickhouse/client/data/array/ClickHouseByteArrayValueTest.java b/clickhouse-client/src/test/java/com/clickhouse/client/data/array/ClickHouseByteArrayValueTest.java new file mode 100644 index 000000000..6da44c153 --- /dev/null +++ b/clickhouse-client/src/test/java/com/clickhouse/client/data/array/ClickHouseByteArrayValueTest.java @@ -0,0 +1,26 @@ +package com.clickhouse.client.data.array; + +import org.junit.Assert; +import org.testng.annotations.Test; + +public class ClickHouseByteArrayValueTest { + @Test(groups = { "unit" }) + public void testConvertToBoolean() throws Exception { + ClickHouseByteArrayValue v = ClickHouseByteArrayValue + .of(new byte[] { 0, 1, -1 }); + Assert.assertArrayEquals(v.getValue(), new byte[] { 0, 1, -1 }); + Assert.assertArrayEquals(v.asArray(Boolean.class), new Boolean[] { false, true, false }); + } + + @Test(groups = { "unit" }) + public void testConvertFromBoolean() throws Exception { + ClickHouseByteArrayValue v = ClickHouseByteArrayValue.ofEmpty(); + Assert.assertArrayEquals(v.getValue(), new byte[0]); + v.update(new boolean[] { false, true, false }); + Assert.assertArrayEquals(v.getValue(), new byte[] { 0, 1, 0 }); + v.resetToNullOrEmpty(); + Assert.assertArrayEquals(v.getValue(), new byte[0]); + v.update(new Boolean[] { Boolean.FALSE, Boolean.FALSE, Boolean.TRUE }); + Assert.assertArrayEquals(v.getValue(), new byte[] { 0, 0, 1 }); + } +}