Skip to content

Commit f26be7d

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix-1551
2 parents f77c115 + 4c3e0eb commit f26be7d

File tree

14 files changed

+404
-29
lines changed

14 files changed

+404
-29
lines changed

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
1-
## 0.6.1
1+
## 0.6.0-patch3
2+
3+
### Bug Fixes
4+
- Not detecting correctly ClickHouse error code
5+
-
6+
## 0.6.0-patch2
7+
8+
### Dependency Updates
9+
- org.apache.commons:commons-compress from 1.23.0 to 1.26.1
10+
- org.postgresql:postgresql from 42.6.0 to 42.6.1
11+
-
12+
## 0.6.0-patch1
213

314
### Bug Fixes
415
- Fix buffering issue caused by decompress flag not to work when working with HTTP Client.

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseClient.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,7 @@ default boolean ping(ClickHouseNode server, int timeout) {
960960
return resp != null;
961961
} catch (Exception e) {
962962
// ignore
963+
e.printStackTrace();
963964
}
964965
}
965966

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseException.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class ClickHouseException extends Exception {
2424
public static final int ERROR_POCO = 1000;
2525
public static final int ERROR_TIMEOUT = 159;
2626
public static final int ERROR_UNKNOWN = 1002;
27+
public static final int ERROR_SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY = 455;
2728

2829
static final String MSG_CODE = "Code: ";
2930
static final String MSG_CONNECT_TIMED_OUT = "connect timed out";

clickhouse-client/src/test/java/com/clickhouse/client/ClientIntegrationTest.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.clickhouse.client.ClickHouseClientBuilder.Agent;
44
import com.clickhouse.client.ClickHouseTransaction.XID;
55
import com.clickhouse.client.config.ClickHouseClientOption;
6-
import com.clickhouse.client.config.ClickHouseSslMode;
76
import com.clickhouse.config.ClickHouseBufferingMode;
87
import com.clickhouse.config.ClickHouseOption;
98
import com.clickhouse.config.ClickHouseRenameMethod;
@@ -44,7 +43,6 @@
4443
import com.clickhouse.data.value.UnsignedShort;
4544

4645
import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorInputStream;
47-
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
4846
import org.testng.Assert;
4947
import org.testng.SkipException;
5048
import org.testng.annotations.DataProvider;
@@ -294,7 +292,12 @@ protected Object[][] getPrimitiveArrayMatrix() {
294292
UnsignedLong.valueOf(5L) } },
295293
{ "Nullable(Float32)", new Float[] { null, -2F, 3F, -4F, 5F } },
296294
{ "Nullable(Float64)", new Double[] { 1D, null, 3D, -4D, 5D } },
295+
};
296+
}
297297

298+
@DataProvider(name = "primitiveArrayLowCardinalityMatrix")
299+
protected Object[][] getPrimitiveArrayLowCardinalityMatrix() {
300+
return new Object[][]{
298301
{ "LowCardinality(Int8)", new int[] { -1, 2, -3, 4, -5 } },
299302
{ "LowCardinality(UInt8)", new int[] { 1, 2, 3, 4, 5 } },
300303
{ "LowCardinality(Int16)", new int[] { -1, 2, -3, 4, -5 } },
@@ -710,6 +713,41 @@ public void testPrimitiveArray(String baseType, Object expectedValues) throws Cl
710713
ClickHouseColumn.of("", baseType)).newArrayValue(server.config).update(expectedValues)
711714
.toSqlExpression()));
712715

716+
checkPrimitiveArrayValues(server, tableName, tableColumns, baseType, expectedValues);
717+
}
718+
719+
@Test(dataProvider = "primitiveArrayLowCardinalityMatrix", groups = "integration")
720+
public void testPrimitiveArrayWithLowCardinality(String baseType, Object expectedValues) throws ClickHouseException {
721+
ClickHouseNode server = getServer();
722+
723+
String tableName = "test_primitive_array_"
724+
+ baseType.replace('(', '_').replace(')', ' ').trim().toLowerCase();
725+
String tableColumns = String.format("a1 Array(%1$s), a2 Array(Array(%1$s)), a3 Array(Array(Array(%1$s)))",
726+
baseType);
727+
try {
728+
sendAndWait(server, "drop table if exists " + tableName,
729+
"create table " + tableName + " (" + tableColumns + ")engine=Memory",
730+
"insert into " + tableName + String.format(
731+
" values(%2$s, [[123],[],[4], %2$s], [[[12],[3],[],[4,5]],[[123],[],[4], %2$s]])", baseType,
732+
ClickHouseColumn.of("", ClickHouseDataType.Array, false,
733+
ClickHouseColumn.of("", baseType)).newArrayValue(server.config).update(expectedValues)
734+
.toSqlExpression()));
735+
} catch (ClickHouseException e) {
736+
try (ClickHouseClient client = getClient()) {
737+
if (e.getErrorCode() == ClickHouseException.ERROR_SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY &&
738+
checkServerVersion(client, server, "[24.2,)")) {
739+
return;
740+
}
741+
} catch ( Exception e1) {
742+
Assert.fail("Failed to check server version", e1);
743+
}
744+
745+
Assert.fail("Exception code is " + e.getErrorCode(), e);
746+
}
747+
checkPrimitiveArrayValues(server, tableName, tableColumns, baseType, expectedValues);
748+
}
749+
750+
private void checkPrimitiveArrayValues(ClickHouseNode server, String tableName, String tableColumns, String baseType, Object expectedValues) throws ClickHouseException {
713751
try (ClickHouseClient client = getClient()) {
714752
ClickHouseRequest<?> request = newRequest(client, server)
715753
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes);
@@ -762,6 +800,7 @@ public void testPrimitiveArray(String baseType, Object expectedValues) throws Cl
762800
}
763801
}
764802

803+
765804
@Test(groups = { "integration" })
766805
public void testQueryWithNoResult() throws ExecutionException, InterruptedException {
767806
String sql = "select * from system.numbers limit 0";

clickhouse-client/src/test/resources/containers/clickhouse-server/config.d/custom_config.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,13 @@
3939
</openSSL>
4040

4141
<custom_settings_prefixes>custom_</custom_settings_prefixes>
42-
42+
4343
<!-- single node cluster: single_node_cluster_localhost -->
4444
<keeper_server>
4545
<force_recovery>1</force_recovery>
4646
<tcp_port>9181</tcp_port>
4747
<server_id>1</server_id>
48+
<enable_ipv6>false</enable_ipv6> <!-- disable ipv6 for docker environment -->
4849

4950
<log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
5051
<snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>

clickhouse-data/src/main/java/com/clickhouse/data/ClickHouseSimpleRecord.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.clickhouse.data;
22

33
import java.util.Collections;
4+
import java.util.HashMap;
45
import java.util.List;
6+
import java.util.Map;
57

68
/**
79
* Default implementation of {@link com.clickhouse.data.ClickHouseRecord},
@@ -13,6 +15,7 @@ public class ClickHouseSimpleRecord implements ClickHouseRecord {
1315

1416
private final List<ClickHouseColumn> columns;
1517
private ClickHouseValue[] values;
18+
private Map<String, Integer> columnsIndexes = null;
1619

1720
/**
1821
* Creates a record object to wrap given values.
@@ -83,19 +86,25 @@ public ClickHouseValue getValue(int index) {
8386

8487
@Override
8588
public ClickHouseValue getValue(String name) {
89+
if(columnsIndexes == null)
90+
columnsIndexes = new HashMap<>(columns.size());
91+
92+
return getValue(columnsIndexes.computeIfAbsent(name, this::computeColumnIndex));
93+
}
94+
95+
@Override
96+
public int size() {
97+
return values.length;
98+
}
99+
100+
private int computeColumnIndex(String name) {
86101
int index = 0;
87102
for (ClickHouseColumn c : columns) {
88103
if (c.getColumnName().equalsIgnoreCase(name)) {
89-
return getValue(index);
104+
return index;
90105
}
91106
index++;
92107
}
93-
94108
throw new IllegalArgumentException(ClickHouseUtils.format("Unable to find column [%s]", name));
95109
}
96-
97-
@Override
98-
public int size() {
99-
return values.length;
100-
}
101110
}

clickhouse-data/src/main/java/com/clickhouse/data/value/ClickHouseArrayValue.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,7 @@
88
import java.time.LocalDate;
99
import java.time.LocalDateTime;
1010
import java.time.LocalTime;
11-
import java.util.Arrays;
12-
import java.util.Collection;
13-
import java.util.Enumeration;
14-
import java.util.LinkedHashMap;
15-
import java.util.LinkedList;
16-
import java.util.List;
17-
import java.util.Map;
18-
import java.util.UUID;
11+
import java.util.*;
1912
import java.util.Map.Entry;
2013
import com.clickhouse.data.ClickHouseArraySequence;
2114
import com.clickhouse.data.ClickHouseChecker;
@@ -595,7 +588,31 @@ public <V extends ClickHouseValue> V getValue(int index, V value) {
595588
@Override
596589
@SuppressWarnings("unchecked")
597590
public ClickHouseArraySequence setValue(int index, ClickHouseValue value) {
598-
getValue()[index] = (T) value.asRawObject();
599-
return this;
591+
try {
592+
getValue()[index] = (T) value.asRawObject();
593+
return this;
594+
} catch (ArrayStoreException arrayStoreException) {
595+
Class<?> existingArrayType = value.asRawObject().getClass();
596+
Class<?> idealArrayType = getValue().getClass();
597+
// Loop to find the root component type
598+
while (existingArrayType.isArray()) {
599+
existingArrayType = existingArrayType.getComponentType();
600+
}
601+
602+
int idealCount = 0;
603+
while (idealArrayType.isArray()) {
604+
idealArrayType = idealArrayType.getComponentType();
605+
idealCount++;
606+
}
607+
608+
// Create a new array of the correct type with the ideal depth
609+
Object newArray = Array.newInstance(existingArrayType, 1);
610+
for (int i = 1; i < idealCount - 1; i++) {
611+
newArray = Array.newInstance(newArray.getClass(), 1);
612+
}
613+
614+
getValue()[index] = (T) newArray;
615+
return this;
616+
}
600617
}
601618
}

clickhouse-data/src/test/java/com/clickhouse/data/format/ClickHouseRowBinaryProcessorTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,17 @@ public boolean isUseBinaryString() {
387387
BinaryStreamUtilsTest.generateInput(1, 2, 0x41, 0x31));
388388
Assert.assertTrue(value instanceof ClickHouseArrayValue);
389389
Assert.assertEquals(value.asObject(), new String[] { "A1" });
390+
value = deserialize(null, config,
391+
ClickHouseColumn.of("a", "Array(Array(Array(Nullable(String))))"),
392+
BinaryStreamUtilsTest.generateInput(1, 1, 1, 1, 1, 1, 2, 0x41, 0x31));
393+
Assert.assertTrue(value instanceof ClickHouseArrayValue);
394+
Assert.assertNotNull(value.asArray());
395+
value = deserialize(null, config,
396+
ClickHouseColumn.of("a", "Array(Array(Array(Nullable(String))))"),
397+
BinaryStreamUtilsTest.generateInput(1, 0));
398+
Assert.assertTrue(value instanceof ClickHouseArrayValue);
399+
//Assert.assertEquals(value.asObject(), new String[][][] { new String[][] { new String[] { "A1" } } });
400+
Assert.assertNotNull(value.asArray());
390401
value = deserialize(null, binConf,
391402
ClickHouseColumn.of("a", "Array(String)"),
392403
BinaryStreamUtilsTest.generateInput(1, 2, 0x41, 0x31));

clickhouse-http-client/src/main/java/com/clickhouse/client/http/ApacheHttpConnectionImpl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,17 @@ private void checkResponse(ClickHouseConfig config, CloseableHttpResponse respon
206206
errorMsg = parseErrorFromException(errorCode != null ? errorCode.getValue() : null,
207207
serverName != null ? serverName.getValue() : null, e, bytes);
208208
}
209+
if (errorMsg != null && errorMsg.isEmpty()) {
210+
// if we have both errorCode and serverName, we can wrap them into the exception message ????
211+
if (errorCode != null && serverName != null ) {
212+
String errorCodeValue = errorCode.getValue();
213+
String serverNameValue = serverName.getValue();
214+
if (errorCodeValue != null && serverNameValue != null) {
215+
throw new IOException(
216+
ClickHouseUtils.format("Code: %s, server: %s, %s", errorCodeValue, serverNameValue, response.toString()));
217+
}
218+
}
219+
}
209220
throw new IOException(errorMsg);
210221
}
211222

0 commit comments

Comments
 (0)