Skip to content

Commit 02542cc

Browse files
authored
fixed reading arrays. fixed converting string to number (#2014)
1 parent fe687bc commit 02542cc

File tree

8 files changed

+73
-21
lines changed

8 files changed

+73
-21
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ protected void setSchema(TableSchema schema) {
251251
case Decimal128:
252252
case Decimal256:
253253
case Bool:
254+
case String:
254255
this.convertions[i] = NumberConverter.NUMBER_CONVERTERS;
255256
break;
256257
default:
@@ -619,7 +620,7 @@ public ClickHouseGeoMultiPolygonValue getGeoMultiPolygon(int index) {
619620

620621
@Override
621622
public <T> List<T> getList(int index) {
622-
return readValue(index);
623+
return getList(schema.indexToName(index));
623624
}
624625

625626
@Override

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ private <T> T readNumberValue(String colName, NumberConverter.NumberType targetT
8181
return (T) converter.apply(value);
8282
} else {
8383
String columnTypeName = schema.getColumnByName(colName).getDataType().name();
84-
throw new ClientException("Column " + colName + " " + columnTypeName +
85-
" cannot be converted to " + targetType.getTypeName());
84+
throw new ClientException("Column '" + colName + "' of type " + columnTypeName +
85+
" cannot be converted to '" + targetType.getTypeName() + "' value");
8686
}
8787
}
8888

@@ -238,7 +238,12 @@ public ClickHouseGeoMultiPolygonValue getGeoMultiPolygon(String colName) {
238238

239239
@Override
240240
public <T> List<T> getList(String colName) {
241-
return getList(schema.nameToIndex(colName));
241+
Object value = readValue(colName);
242+
if (value instanceof BinaryStreamReader.ArrayValue) {
243+
return ((BinaryStreamReader.ArrayValue) value).asList();
244+
} else {
245+
throw new ClientException("Column is not of array type");
246+
}
242247
}
243248

244249

@@ -388,12 +393,7 @@ public ClickHouseGeoMultiPolygonValue getGeoMultiPolygon(int index) {
388393

389394
@Override
390395
public <T> List<T> getList(int index) {
391-
Object value = readValue(index);
392-
if (value instanceof BinaryStreamReader.ArrayValue) {
393-
return ((BinaryStreamReader.ArrayValue) value).asList();
394-
} else {
395-
throw new ClientException("Column is not of array type");
396-
}
396+
return getList(schema.indexToName(index));
397397
}
398398

399399
@Override

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ public static BigDecimal toBigDecimal(Object value) {
153153
}
154154
}
155155

156-
157156
static Map<NumberType, Function<Object, ?>> getNumberConverters() {
158157
Map<NumberType, Function<Object, ?>> converters = new HashMap<>();
159158
converters.put(NumberType.Byte, NumberConverter::toByte);

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,15 @@ public void testArrayValues() throws Exception {
549549
Assert.assertEquals(col4Array, ((List)data.get(0).get("col4")).toArray());
550550
}
551551

552+
@Test
553+
public void testArraysAsList() {
554+
GenericRecord record =
555+
client.queryAll("SELECT [] as empty_array").get(0);
556+
557+
List<Object> items = record.getList("empty_array");
558+
Assert.assertTrue(items.isEmpty());
559+
}
560+
552561
private final static List<String> MAP_COLUMNS = Arrays.asList(
553562
"col1 Map(String, Int8)",
554563
"col2 Map(String, String)"
@@ -1218,6 +1227,25 @@ public void testStringDataTypes() {
12181227
testDataTypes(columns, valueGenerators, verifiers);
12191228
}
12201229

1230+
1231+
@Test
1232+
public void testNumberToStringConvertions() throws Exception {
1233+
1234+
GenericRecord record =
1235+
client.queryAll("SELECT '100' as small_number, '100500' as number").get(0);
1236+
1237+
Assert.assertEquals(record.getString("number"), "100500");
1238+
Assert.assertEquals(record.getString("small_number"), "100");
1239+
Assert.assertEquals(record.getByte("small_number"), 100);
1240+
Assert.assertEquals(record.getShort("small_number"), 100);
1241+
Assert.assertThrows(() -> record.getShort("number"));
1242+
Assert.assertEquals(record.getInteger("number"), 100500);
1243+
Assert.assertEquals(record.getLong("number"), 100500L);
1244+
Assert.assertEquals(record.getFloat("number"), 100500.0F);
1245+
Assert.assertEquals(record.getBigInteger("number"), BigInteger.valueOf(100500L));
1246+
1247+
}
1248+
12211249
private static String sq(String str) {
12221250
return "\'" + str + "\'";
12231251
}

jdbc-v2/src/main/java/com/clickhouse/jdbc/ConnectionImpl.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
import com.clickhouse.client.api.query.GenericRecord;
66
import com.clickhouse.client.api.query.QuerySettings;
77
import com.clickhouse.jdbc.internal.ClientInfoProperties;
8-
import com.clickhouse.jdbc.internal.DriverProperties;
98
import com.clickhouse.jdbc.internal.JdbcConfiguration;
109
import com.clickhouse.jdbc.internal.ExceptionUtils;
1110
import com.clickhouse.jdbc.internal.JdbcConfiguration;
11+
import com.clickhouse.jdbc.internal.JdbcUtils;
1212
import org.slf4j.Logger;
1313
import org.slf4j.LoggerFactory;
1414

@@ -30,6 +30,7 @@
3030
import java.sql.ShardingKey;
3131
import java.sql.Statement;
3232
import java.sql.Struct;
33+
import java.sql.Types;
3334
import java.util.HashSet;
3435
import java.util.List;
3536
import java.util.Map;
@@ -425,7 +426,8 @@ public Properties getClientInfo() throws SQLException {
425426
@Override
426427
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
427428
try {
428-
return new com.clickhouse.jdbc.types.Array(List.of(elements));
429+
// TODO: pass type name
430+
return new com.clickhouse.jdbc.types.Array(List.of(elements), Types.OTHER);
429431
} catch (Exception e) {
430432
throw new SQLException("Failed to create array", ExceptionUtils.SQL_STATE_CLIENT_ERROR, e);
431433
}

jdbc-v2/src/main/java/com/clickhouse/jdbc/ResultSetImpl.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
import com.clickhouse.client.api.data_formats.ClickHouseBinaryFormatReader;
1818
import com.clickhouse.client.api.metadata.TableSchema;
1919
import com.clickhouse.client.api.query.QueryResponse;
20+
import com.clickhouse.data.ClickHouseColumn;
2021
import com.clickhouse.jdbc.internal.ExceptionUtils;
22+
import com.clickhouse.jdbc.internal.JdbcUtils;
2123
import com.clickhouse.jdbc.types.Array;
2224
import org.slf4j.Logger;
2325
import org.slf4j.LoggerFactory;
@@ -1080,11 +1082,7 @@ public java.sql.Clob getClob(int columnIndex) throws SQLException {
10801082
@Override
10811083
public java.sql.Array getArray(int columnIndex) throws SQLException {
10821084
checkClosed();
1083-
try {
1084-
return new Array(reader.getList(columnIndex));
1085-
} catch (Exception e) {
1086-
throw ExceptionUtils.toSqlState(e);
1087-
}
1085+
return getArray(reader.getSchema().indexToName(columnIndex));
10881086
}
10891087

10901088
@Override
@@ -1115,7 +1113,8 @@ public Clob getClob(String columnLabel) throws SQLException {
11151113
public java.sql.Array getArray(String columnLabel) throws SQLException {
11161114
checkClosed();
11171115
try {
1118-
return new Array(reader.getList(columnLabel));
1116+
ClickHouseColumn column = reader.getSchema().getColumnByName(columnLabel);
1117+
return new Array(reader.getList(columnLabel), JdbcUtils.convertToSqlType(column.getArrayBaseColumn().getDataType()));
11191118
} catch (Exception e) {
11201119
throw ExceptionUtils.toSqlState(e);
11211120
}

jdbc-v2/src/main/java/com/clickhouse/jdbc/types/Array.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ public class Array implements java.sql.Array {
1616
Object[] array;
1717
int type; //java.sql.Types
1818

19-
public Array(List<Object> list) throws SQLException {
19+
public Array(List<Object> list, int itemType) throws SQLException {
2020
if (list == null) {
2121
throw ExceptionUtils.toSqlState(new IllegalArgumentException("List cannot be null"));
2222
}
2323

2424
this.array = list.toArray();
25-
this.type = Types.OTHER;
25+
this.type = itemType;
2626
}
2727

2828
@Override

jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.testng.Assert;
55
import org.testng.annotations.Test;
66

7+
import java.sql.Array;
78
import java.sql.Connection;
89
import java.sql.Date;
910
import java.sql.ResultSet;
@@ -14,6 +15,7 @@
1415
import java.util.List;
1516
import java.util.Properties;
1617

18+
import static org.testng.Assert.*;
1719
import static org.testng.Assert.assertEquals;
1820
import static org.testng.Assert.assertFalse;
1921
import static org.testng.Assert.assertNull;
@@ -381,4 +383,25 @@ record = conn.client.queryAll("SELECT currentRoles()").get(0);
381383
assertEquals(record.getList(1).size(), 2);
382384
}
383385
}
386+
387+
@Test
388+
public void testGettingArrays() throws Exception {
389+
try (ConnectionImpl conn = (ConnectionImpl) getJdbcConnection();
390+
Statement stmt = conn.createStatement()) {
391+
392+
ResultSet rs = stmt.executeQuery("SELECT [] as empty_array, [1, 2, 3] as number_array, " +
393+
" ['val1', 'val2', 'val3'] as str_array");
394+
395+
assertTrue(rs.next());
396+
Array emptyArray = rs.getArray("empty_array");
397+
assertEquals(((Object[]) emptyArray.getArray()).length, 0);
398+
Array numberArray = rs.getArray("number_array");
399+
assertEquals(((Object[]) numberArray.getArray()).length, 3);
400+
System.out.println(((Object[]) numberArray.getArray())[0].getClass().getName());
401+
assertEquals(numberArray.getArray(), new short[] {1, 2, 3} );
402+
Array stringArray = rs.getArray("str_array");
403+
assertEquals(((Object[]) stringArray.getArray()).length, 3);
404+
assertEquals(Arrays.stream(((Object[]) stringArray.getArray())).toList(), Arrays.asList("val1", "val2", "val3"));
405+
}
406+
}
384407
}

0 commit comments

Comments
 (0)