Skip to content

Commit d7856fd

Browse files
committed
Fixed array convert with multidimension
1 parent cfe6315 commit d7856fd

File tree

2 files changed

+55
-27
lines changed

2 files changed

+55
-27
lines changed

jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcUtils.java

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ public static Object convert(Object value, Class<?> type, ClickHouseColumn colum
267267

268268
if (column != null && column.getArrayBaseColumn() != null) {
269269
ClickHouseDataType baseType = column.getArrayBaseColumn().getDataType();
270-
Object[] convertedValues = convertList(listValue, convertToJavaClass(baseType), column.getArrayNestedLevel());
270+
Object[] convertedValues = convertList(listValue, convertToJavaClass(baseType),
271+
column.getArrayNestedLevel());
271272
return new Array(column, convertedValues);
272273
}
273274

@@ -288,7 +289,8 @@ public static Object convert(Object value, Class<?> type, ClickHouseColumn colum
288289

289290
if (column != null && column.getArrayBaseColumn() != null) {
290291
ClickHouseDataType baseType = column.getArrayBaseColumn().getDataType();
291-
Object[] convertedValues = convertArray(arrayValue.getArrayOfObjects(), convertToJavaClass(baseType));
292+
Object[] convertedValues = convertArray(arrayValue.getArray(), convertToJavaClass(baseType),
293+
column.getArrayNestedLevel());
292294
return new Array(column, convertedValues);
293295
}
294296

@@ -359,16 +361,12 @@ public static <T> T[] convertList(List<?> values, Class<T> type, int dimensions)
359361
if (values == null) {
360362
return null;
361363
}
362-
if (values.isEmpty()) {
363-
return (T[]) java.lang.reflect.Array.newInstance(type, 0);
364-
}
365-
366364

367365
int[] arrayDimensions = new int[dimensions];
368366
arrayDimensions[0] = values.size();
369367
T[] convertedValues = (T[]) java.lang.reflect.Array.newInstance(type, arrayDimensions);
370368
Stack<ArrayProcessingCursor> stack = new Stack<>();
371-
stack.push(new ArrayProcessingCursor(convertedValues, values, 0, values.size()));
369+
stack.push(new ArrayProcessingCursor(convertedValues, values, values.size()));
372370

373371
while (!stack.isEmpty()) {
374372
ArrayProcessingCursor cursor = stack.pop();
@@ -382,7 +380,7 @@ public static <T> T[] convertList(List<?> values, Class<T> type, int dimensions)
382380
arrayDimensions = new int[Math.max(dimensions - stack.size() - 1, 1)];
383381
arrayDimensions[0] = srcList.size();
384382
T[] targetArray = (T[]) java.lang.reflect.Array.newInstance(type, arrayDimensions);
385-
stack.push(new ArrayProcessingCursor(targetArray, value, 0, srcList.size()));
383+
stack.push(new ArrayProcessingCursor(targetArray, value, srcList.size()));
386384
java.lang.reflect.Array.set(cursor.targetArray, i, targetArray);
387385
} else {
388386
java.lang.reflect.Array.set(cursor.targetArray, i, convert(value, type));
@@ -393,28 +391,55 @@ public static <T> T[] convertList(List<?> values, Class<T> type, int dimensions)
393391
return convertedValues;
394392
}
395393

396-
public static <T> T[] convertArray(Object[] values, Class<T> type) throws SQLException {
394+
/**
395+
* Convert array to java array and all its elements
396+
* @param values
397+
* @param type
398+
* @param dimensions
399+
* @return
400+
* @param <T>
401+
* @throws SQLException
402+
*/
403+
public static <T> T[] convertArray(Object values, Class<T> type, int dimensions) throws SQLException {
397404
if (values == null) {
398405
return null;
399406
}
400-
T[] convertedValues = (T[]) java.lang.reflect.Array.newInstance(type, values.length);
401-
for (int i = 0; i < values.length; i++) {
402-
convertedValues[i] = (T) convert(values[i], type);
407+
408+
int[] arrayDimensions = new int[dimensions];
409+
arrayDimensions[0] = java.lang.reflect.Array.getLength(values);
410+
T[] convertedValues = (T[]) java.lang.reflect.Array.newInstance(type, arrayDimensions);
411+
Stack<ArrayProcessingCursor> stack = new Stack<>();
412+
stack.push(new ArrayProcessingCursor(convertedValues, values, arrayDimensions[0]));
413+
414+
while (!stack.isEmpty()) {
415+
ArrayProcessingCursor cursor = stack.pop();
416+
417+
for (int i = 0; i < cursor.size; i++) {
418+
Object value = cursor.getValue(i);
419+
if (value == null) {
420+
continue; // no need to set null value
421+
} else if (value.getClass().isArray()) {
422+
arrayDimensions = new int[Math.max(dimensions - stack.size() - 1, 1)];
423+
arrayDimensions[0] = java.lang.reflect.Array.getLength(value);
424+
T[] targetArray = (T[]) java.lang.reflect.Array.newInstance(type, arrayDimensions);
425+
stack.push(new ArrayProcessingCursor(targetArray, value, arrayDimensions[0]));
426+
java.lang.reflect.Array.set(cursor.targetArray, i, targetArray);
427+
} else {
428+
java.lang.reflect.Array.set(cursor.targetArray, i, convert(value, type));
429+
}
430+
}
403431
}
432+
404433
return convertedValues;
405434
}
406435

407436
private static final class ArrayProcessingCursor {
408437
private final Object targetArray;
409-
private final Object srcArray;
410-
private final int pos;
411438
private final int size;
412439
private final Function<Integer, Object> valueGetter;
413440

414-
public ArrayProcessingCursor(Object targetArray, Object srcArray, int pos, int size) {
441+
public ArrayProcessingCursor(Object targetArray, Object srcArray, int size) {
415442
this.targetArray = targetArray;
416-
this.srcArray = srcArray;
417-
this.pos = pos;
418443
this.size = size;
419444
if (srcArray instanceof List<?>) {
420445
List<?> list = (List<?>) srcArray;

jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcUtilsTest.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,19 @@ public void testConvertToArray() throws Exception {
5050
@Test(groups = {"unit"})
5151
public void testConvertArray() throws Exception {
5252
// primitive classes are unwrapped
53-
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Boolean.class), new Boolean[] { false, true });
54-
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Byte.class), new Byte[] { 0, 1 });
55-
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Short.class), new Short[] { 0, 1 });
56-
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Integer.class), new Integer[] { 0, 1 });
57-
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Long.class), new Long[] { 0L, 1L });
58-
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Float.class), new Float[] { 0.0f, 1.0f });
59-
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Double.class), new Double[] { 0.0, 1.0 });
60-
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, String.class), new String[] { "0", "1" });
61-
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, BigDecimal.class), new BigDecimal[] { BigDecimal.valueOf(0), BigDecimal.valueOf(1) });
62-
assertNull(JdbcUtils.convertArray(null, Integer.class));
53+
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Boolean.class, 1), new Boolean[] { false, true });
54+
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Byte.class, 1), new Byte[] { 0, 1 });
55+
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Short.class, 1), new Short[] { 0, 1 });
56+
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Integer.class, 1), new Integer[] { 0, 1 });
57+
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Long.class, 1), new Long[] { 0L, 1L });
58+
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Float.class, 1), new Float[] { 0.0f, 1.0f });
59+
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, Double.class, 1), new Double[] { 0.0, 1.0 });
60+
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, String.class, 1), new String[] { "0", "1" });
61+
assertEquals(JdbcUtils.convertArray(new Object[] { 0, 1 }, BigDecimal.class, 1), new BigDecimal[] { BigDecimal.valueOf(0), BigDecimal.valueOf(1) });
62+
assertEquals(JdbcUtils.convertArray(new Object[][] { new Object[] {1, 2, 3}, new Object[] { 4, 5, 6} }, String.class, 2),
63+
new String[][] { new String[] {"1", "2", "3"}, new String[] {"4", "5", "6"} });
64+
65+
assertNull(JdbcUtils.convertArray(null, Integer.class, 1));
6366
}
6467

6568

0 commit comments

Comments
 (0)