Skip to content

Commit

Permalink
fixed reading arrays. fixed converting string to number (#2014)
Browse files Browse the repository at this point in the history
  • Loading branch information
chernser authored Dec 12, 2024
1 parent fe687bc commit 02542cc
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ protected void setSchema(TableSchema schema) {
case Decimal128:
case Decimal256:
case Bool:
case String:
this.convertions[i] = NumberConverter.NUMBER_CONVERTERS;
break;
default:
Expand Down Expand Up @@ -619,7 +620,7 @@ public ClickHouseGeoMultiPolygonValue getGeoMultiPolygon(int index) {

@Override
public <T> List<T> getList(int index) {
return readValue(index);
return getList(schema.indexToName(index));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ private <T> T readNumberValue(String colName, NumberConverter.NumberType targetT
return (T) converter.apply(value);
} else {
String columnTypeName = schema.getColumnByName(colName).getDataType().name();
throw new ClientException("Column " + colName + " " + columnTypeName +
" cannot be converted to " + targetType.getTypeName());
throw new ClientException("Column '" + colName + "' of type " + columnTypeName +
" cannot be converted to '" + targetType.getTypeName() + "' value");
}
}

Expand Down Expand Up @@ -238,7 +238,12 @@ public ClickHouseGeoMultiPolygonValue getGeoMultiPolygon(String colName) {

@Override
public <T> List<T> getList(String colName) {
return getList(schema.nameToIndex(colName));
Object value = readValue(colName);
if (value instanceof BinaryStreamReader.ArrayValue) {
return ((BinaryStreamReader.ArrayValue) value).asList();
} else {
throw new ClientException("Column is not of array type");
}
}


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

@Override
public <T> List<T> getList(int index) {
Object value = readValue(index);
if (value instanceof BinaryStreamReader.ArrayValue) {
return ((BinaryStreamReader.ArrayValue) value).asList();
} else {
throw new ClientException("Column is not of array type");
}
return getList(schema.indexToName(index));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ public static BigDecimal toBigDecimal(Object value) {
}
}


static Map<NumberType, Function<Object, ?>> getNumberConverters() {
Map<NumberType, Function<Object, ?>> converters = new HashMap<>();
converters.put(NumberType.Byte, NumberConverter::toByte);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,15 @@ public void testArrayValues() throws Exception {
Assert.assertEquals(col4Array, ((List)data.get(0).get("col4")).toArray());
}

@Test
public void testArraysAsList() {
GenericRecord record =
client.queryAll("SELECT [] as empty_array").get(0);

List<Object> items = record.getList("empty_array");
Assert.assertTrue(items.isEmpty());
}

private final static List<String> MAP_COLUMNS = Arrays.asList(
"col1 Map(String, Int8)",
"col2 Map(String, String)"
Expand Down Expand Up @@ -1218,6 +1227,25 @@ public void testStringDataTypes() {
testDataTypes(columns, valueGenerators, verifiers);
}


@Test
public void testNumberToStringConvertions() throws Exception {

GenericRecord record =
client.queryAll("SELECT '100' as small_number, '100500' as number").get(0);

Assert.assertEquals(record.getString("number"), "100500");
Assert.assertEquals(record.getString("small_number"), "100");
Assert.assertEquals(record.getByte("small_number"), 100);
Assert.assertEquals(record.getShort("small_number"), 100);
Assert.assertThrows(() -> record.getShort("number"));
Assert.assertEquals(record.getInteger("number"), 100500);
Assert.assertEquals(record.getLong("number"), 100500L);
Assert.assertEquals(record.getFloat("number"), 100500.0F);
Assert.assertEquals(record.getBigInteger("number"), BigInteger.valueOf(100500L));

}

private static String sq(String str) {
return "\'" + str + "\'";
}
Expand Down
6 changes: 4 additions & 2 deletions jdbc-v2/src/main/java/com/clickhouse/jdbc/ConnectionImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import com.clickhouse.client.api.query.GenericRecord;
import com.clickhouse.client.api.query.QuerySettings;
import com.clickhouse.jdbc.internal.ClientInfoProperties;
import com.clickhouse.jdbc.internal.DriverProperties;
import com.clickhouse.jdbc.internal.JdbcConfiguration;
import com.clickhouse.jdbc.internal.ExceptionUtils;
import com.clickhouse.jdbc.internal.JdbcConfiguration;
import com.clickhouse.jdbc.internal.JdbcUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -30,6 +30,7 @@
import java.sql.ShardingKey;
import java.sql.Statement;
import java.sql.Struct;
import java.sql.Types;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -425,7 +426,8 @@ public Properties getClientInfo() throws SQLException {
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
try {
return new com.clickhouse.jdbc.types.Array(List.of(elements));
// TODO: pass type name
return new com.clickhouse.jdbc.types.Array(List.of(elements), Types.OTHER);
} catch (Exception e) {
throw new SQLException("Failed to create array", ExceptionUtils.SQL_STATE_CLIENT_ERROR, e);
}
Expand Down
11 changes: 5 additions & 6 deletions jdbc-v2/src/main/java/com/clickhouse/jdbc/ResultSetImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
import com.clickhouse.client.api.data_formats.ClickHouseBinaryFormatReader;
import com.clickhouse.client.api.metadata.TableSchema;
import com.clickhouse.client.api.query.QueryResponse;
import com.clickhouse.data.ClickHouseColumn;
import com.clickhouse.jdbc.internal.ExceptionUtils;
import com.clickhouse.jdbc.internal.JdbcUtils;
import com.clickhouse.jdbc.types.Array;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -1080,11 +1082,7 @@ public java.sql.Clob getClob(int columnIndex) throws SQLException {
@Override
public java.sql.Array getArray(int columnIndex) throws SQLException {
checkClosed();
try {
return new Array(reader.getList(columnIndex));
} catch (Exception e) {
throw ExceptionUtils.toSqlState(e);
}
return getArray(reader.getSchema().indexToName(columnIndex));
}

@Override
Expand Down Expand Up @@ -1115,7 +1113,8 @@ public Clob getClob(String columnLabel) throws SQLException {
public java.sql.Array getArray(String columnLabel) throws SQLException {
checkClosed();
try {
return new Array(reader.getList(columnLabel));
ClickHouseColumn column = reader.getSchema().getColumnByName(columnLabel);
return new Array(reader.getList(columnLabel), JdbcUtils.convertToSqlType(column.getArrayBaseColumn().getDataType()));
} catch (Exception e) {
throw ExceptionUtils.toSqlState(e);
}
Expand Down
4 changes: 2 additions & 2 deletions jdbc-v2/src/main/java/com/clickhouse/jdbc/types/Array.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ public class Array implements java.sql.Array {
Object[] array;
int type; //java.sql.Types

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

this.array = list.toArray();
this.type = Types.OTHER;
this.type = itemType;
}

@Override
Expand Down
23 changes: 23 additions & 0 deletions jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.testng.Assert;
import org.testng.annotations.Test;

import java.sql.Array;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
Expand All @@ -14,6 +15,7 @@
import java.util.List;
import java.util.Properties;

import static org.testng.Assert.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
Expand Down Expand Up @@ -381,4 +383,25 @@ record = conn.client.queryAll("SELECT currentRoles()").get(0);
assertEquals(record.getList(1).size(), 2);
}
}

@Test
public void testGettingArrays() throws Exception {
try (ConnectionImpl conn = (ConnectionImpl) getJdbcConnection();
Statement stmt = conn.createStatement()) {

ResultSet rs = stmt.executeQuery("SELECT [] as empty_array, [1, 2, 3] as number_array, " +
" ['val1', 'val2', 'val3'] as str_array");

assertTrue(rs.next());
Array emptyArray = rs.getArray("empty_array");
assertEquals(((Object[]) emptyArray.getArray()).length, 0);
Array numberArray = rs.getArray("number_array");
assertEquals(((Object[]) numberArray.getArray()).length, 3);
System.out.println(((Object[]) numberArray.getArray())[0].getClass().getName());
assertEquals(numberArray.getArray(), new short[] {1, 2, 3} );
Array stringArray = rs.getArray("str_array");
assertEquals(((Object[]) stringArray.getArray()).length, 3);
assertEquals(Arrays.stream(((Object[]) stringArray.getArray())).toList(), Arrays.asList("val1", "val2", "val3"));
}
}
}

0 comments on commit 02542cc

Please sign in to comment.