Skip to content

Commit af242ac

Browse files
committed
added JSON validation in JDBC tests
1 parent a5f8712 commit af242ac

File tree

6 files changed

+84
-20
lines changed

6 files changed

+84
-20
lines changed

client-v2/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
<groupId>com.fasterxml.jackson.core</groupId>
8989
<artifactId>jackson-databind</artifactId>
9090
<scope>test</scope>
91-
<version>2.17.2</version>
91+
<version>${jackson.version}</version>
9292
</dependency>
9393
<dependency>
9494
<groupId>${project.parent.groupId}</groupId>

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public class BinaryStreamReader {
5454

5555
private final Class<?> arrayDefaultTypeHint;
5656

57+
private static final int SB_INIT_SIZE = 100;
58+
5759
/**
5860
* Createa a BinaryStreamReader instance that will use the provided buffer allocator.
5961
*
@@ -1159,7 +1161,7 @@ private ClickHouseColumn readDynamicData() throws IOException {
11591161
return ClickHouseColumn.of("v", typeName);
11601162
} else if (tag == ClickHouseDataType.TUPLE_WITH_NAMES_BIN_TAG || tag == ClickHouseDataType.TUPLE_WITHOUT_NAMES_BIN_TAG) {
11611163
int size = readVarInt(input);
1162-
StringBuilder typeNameBuilder = new StringBuilder();
1164+
StringBuilder typeNameBuilder = new StringBuilder(SB_INIT_SIZE);
11631165
typeNameBuilder.append("Tuple(");
11641166
final boolean readName = tag == ClickHouseDataType.TUPLE_WITH_NAMES_BIN_TAG;
11651167
for (int i = 0; i < size; i++) {
@@ -1249,7 +1251,7 @@ private ClickHouseColumn readDynamicData() throws IOException {
12491251
int maxDynamicPaths = readVarInt(input);
12501252
byte maxDynamicTypes = readByte();
12511253
int numberOfTypedPaths = readVarInt(input);
1252-
StringBuilder typeDef = new StringBuilder();
1254+
StringBuilder typeDef = new StringBuilder(SB_INIT_SIZE);
12531255
typeDef.append("JSON(max_dynamic_paths=").append(maxDynamicPaths).append(",max_dynamic_types=").append(maxDynamicTypes).append(",");
12541256
for (int i = 0; i < numberOfTypedPaths; i++) {
12551257
typeDef.append(readString(input)).append(' '); // path
@@ -1279,7 +1281,7 @@ private ClickHouseColumn readDynamicData() throws IOException {
12791281
}
12801282
case Nested: {
12811283
int size = readVarInt(input);
1282-
StringBuilder nested = new StringBuilder();
1284+
StringBuilder nested = new StringBuilder(SB_INIT_SIZE);
12831285
nested.append("Nested(");
12841286
for (int i = 0; i < size; i++) {
12851287
String name = readString(input);
@@ -1299,7 +1301,7 @@ private ClickHouseColumn readDynamicData() throws IOException {
12991301
}
13001302
case Variant: {
13011303
int variants = readVarInt(input);
1302-
StringBuilder variant = new StringBuilder();
1304+
StringBuilder variant = new StringBuilder(SB_INIT_SIZE);
13031305
variant.append("Variant(");
13041306
for (int i = 0; i < variants; i++) {
13051307
ClickHouseColumn column = readDynamicData();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ private static void serializeTime64(OutputStream stream, Object value) throws IO
663663
} else if (value instanceof Long) {
664664
BinaryStreamUtils.writeUnsignedInt64(stream, (Long) value);
665665
} else if (value instanceof Instant) {
666-
BinaryStreamUtils.writeUnsignedInt64(stream,BigInteger.valueOf(((Instant) value).getEpochSecond() * 1_000_000_000L)
666+
BinaryStreamUtils.writeUnsignedInt64(stream, BigInteger.valueOf(((Instant) value).getEpochSecond() * 1_000_000_000L)
667667
.add(BigInteger.valueOf(((Instant) value).getNano())));
668668
} else {
669669
throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to Time64");

jdbc-v2/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@
4949
</dependency>
5050

5151
<!-- Test dependencies -->
52+
<dependency>
53+
<groupId>com.fasterxml.jackson.core</groupId>
54+
<artifactId>jackson-databind</artifactId>
55+
<scope>test</scope>
56+
<version>${jackson.version}</version>
57+
</dependency>
58+
5259
<dependency>
5360
<groupId>${project.parent.groupId}</groupId>
5461
<artifactId>clickhouse-client</artifactId>

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

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
import com.clickhouse.data.ClickHouseDataType;
88
import com.clickhouse.data.ClickHouseVersion;
99
import com.clickhouse.data.Tuple;
10+
import com.fasterxml.jackson.core.type.TypeReference;
11+
import com.fasterxml.jackson.databind.DeserializationFeature;
12+
import com.fasterxml.jackson.databind.ObjectMapper;
1013
import org.slf4j.Logger;
1114
import org.slf4j.LoggerFactory;
1215
import org.testng.annotations.BeforeClass;
1316
import org.testng.annotations.DataProvider;
1417
import org.testng.annotations.Test;
1518

19+
import java.io.IOException;
1620
import java.math.BigDecimal;
1721
import java.math.BigInteger;
1822
import java.net.Inet4Address;
@@ -1961,8 +1965,10 @@ public void testGeoMultiPolygon() throws Exception {
19611965
}
19621966
}
19631967

1968+
private static final HashMap<String, Object> EMPTY_JSON = new HashMap<>();
1969+
19641970
@Test(groups = { "integration" }, dataProvider = "testJSONReadDP")
1965-
public void testJSONRead(String json) throws Exception {
1971+
public void testJSONRead(String json, Object expected) throws Exception {
19661972
if (ClickHouseVersion.of(getServerVersion()).check("(,24.8]")) {
19671973
return; // JSON was introduced in 24.10
19681974
}
@@ -1979,29 +1985,77 @@ public void testJSONRead(String json) throws Exception {
19791985

19801986
assertTrue(rs.next());
19811987
Object jsonObj = rs.getObject(1);
1988+
if (expected == null) {
1989+
expected = jsonToClientMap(json);
1990+
}
1991+
assertEquals(jsonObj, expected);
19821992
assertTrue(rs.next());
19831993
Object emptyJsonObj = rs.getObject(1);
1994+
assertEquals(emptyJsonObj, EMPTY_JSON);
19841995
assertFalse(rs.next());
19851996
}
19861997
}
19871998
}
19881999

2000+
private final ObjectMapper objectMapper = new ObjectMapper()
2001+
.enable(DeserializationFeature.USE_LONG_FOR_INTS);
2002+
2003+
private HashMap<String, Object> jsonToClientMap(String json) {
2004+
try {
2005+
return objectMapper.readValue(json, new TypeReference<HashMap<String, Object>>() {});
2006+
} catch (IOException e) {
2007+
throw new RuntimeException("Failed to read json to Map<String, Object>", e);
2008+
}
2009+
}
2010+
19892011
@DataProvider(name = "testJSONReadDP")
19902012
public Object[][] testJSONReadDP() {
2013+
Map<String, Object> map1 = new HashMap<>();
2014+
map1.put("nested.key", "value");
2015+
Map<String, Object> map2 = new HashMap<>();
2016+
map2.put("nested.numbers",new ArrayList<Long>() {{ add(1L); add(2L); add(3L); }});
2017+
Map<String, Object> map3 = new HashMap<>();
2018+
map3.put("nested.strings", new ArrayList<>() {{ add("one"); add("two"); add("three"); }});
2019+
Map<String, Object> map4 = new HashMap<>();
2020+
map4.put("array", new ArrayList<HashMap<String,Object>>() {{
2021+
add(new HashMap<>() {{
2022+
put("nested.key", "value");
2023+
}});
2024+
add(new HashMap<>() {{
2025+
put("nested.numbers", new ArrayList<Long>() {{
2026+
add(1L);
2027+
add(2L);
2028+
add(3L);
2029+
}});
2030+
}});
2031+
}});
2032+
Map<String, Object> map5 = new HashMap<>();
2033+
map5.put("array", new ArrayList<HashMap<String,Object>>() {{
2034+
add(new HashMap<>() {{
2035+
put("nested.strings", new ArrayList<>() {{ add("one"); add("two"); add("three"); }});
2036+
2037+
}});
2038+
}});
2039+
Map<String, Object> map6 = new HashMap<>();
2040+
map6.put("level1.level2.level3", "value");
2041+
2042+
Map<String, Object> map7 = new HashMap<>();
2043+
map7.put("level1.level2.level3.level4", "value");
2044+
19912045
return new Object[][] {
1992-
{"{\"key\": \"value\"}"}, // Simple object
1993-
{"{\"numbers\":[1, 2, 3]}"},
1994-
{"{\"strings\":[\"one\", \"two\", \"three\"]}"},
1995-
{"{\"nested\":{\"key\": \"value\"}}"}, // nested objects
1996-
{"{\"nested\":{\"numbers\":[1, 2, 3]}}"}, // nested objects
1997-
{"{\"nested\":{\"strings\":[\"one\", \"two\", \"three\"]}}"}, // nested objects
1998-
{"{\"array\":[{\"key\": \"value\"},{\"key\": \"value\"}]}"}, // array of objects
1999-
{"{\"array\":[{\"numbers\":[1, 2, 3]},{\"strings\":[\"one\", \"two\", \"three\"]}]}"}, // array of objects
2000-
{"{\"array\":[{\"nested\":{\"key\": \"value\"}},{\"nested\":{\"numbers\":[1, 2, 3]}}]}"}, // array of objects
2001-
{"{\"array\":[{\"nested\":{\"strings\":[\"one\", \"two\", \"three\"]}}]}"}, // array of objects
2002-
{"{\"array\":[{\"nested\":[{\"key\": \"value\"}]}]}"}, // simple array of objects
2003-
{"{\"level1\": {\"level2\": {\"level3\": \"value\"}}}"}, // deep nested objects
2004-
{"{\"level1\": {\"level2\": {\"level3\": {\"level4\": \"value\"}}}}"}, // deep nested objects
2046+
{"{\"key\": \"value\"}", null}, // Simple object
2047+
{"{\"numbers\":[1, 2, 3]}", null},
2048+
{"{\"strings\":[\"one\", \"two\", \"three\"]}", null},
2049+
{"{\"nested\":{\"key\": \"value\"}}", map1}, // nested objects
2050+
{"{\"nested\":{\"numbers\":[1, 2, 3]}}", map2}, // nested objects
2051+
{"{\"nested\":{\"strings\":[\"one\", \"two\", \"three\"]}}", map3}, // nested objects
2052+
{"{\"array\":[{\"key\": \"value\"},{\"key\": \"value\"}]}", null}, // array of objects
2053+
{"{\"array\":[{\"numbers\":[1, 2, 3]},{\"strings\":[\"one\", \"two\", \"three\"]}]}", null}, // array of objects
2054+
{"{\"array\":[{\"nested\":{\"key\": \"value\"}},{\"nested\":{\"numbers\":[1, 2, 3]}}]}", map4}, // array of objects
2055+
{"{\"array\":[{\"nested\":{\"strings\":[\"one\", \"two\", \"three\"]}}]}", map5}, // array of objects
2056+
{"{\"array\":[{\"nested\":[{\"key\": \"value\"}]}]}", null}, // simple array of objects
2057+
{"{\"level1\": {\"level2\": {\"level3\": \"value\"}}}", map6}, // deep nested objects
2058+
{"{\"level1\": {\"level2\": {\"level3\": {\"level4\": \"value\"}}}}", map7}, // deep nested objects
20052059

20062060
};
20072061
}

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
<jmh.version>1.37</jmh.version>
138138
<guava.version>33.4.6-jre</guava.version>
139139
<sonar.publish-pluing.version>0.8.0</sonar.publish-pluing.version>
140+
<jackson.version>2.17.2</jackson.version>
140141

141142
<minTargetJdk>17</minTargetJdk>
142143
<minSourceJdk>17</minSourceJdk>

0 commit comments

Comments
 (0)