Skip to content

Commit 20314c6

Browse files
authored
Merge branch 'main' into v2_connection_metrics
2 parents 264fa7a + 208d547 commit 20314c6

File tree

49 files changed

+1725
-196
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1725
-196
lines changed

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

+8-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.function.Function;
2727

2828
import com.clickhouse.client.config.ClickHouseClientOption;
29+
import com.clickhouse.client.config.ClickHouseDefaults;
2930
import com.clickhouse.config.ClickHouseConfigChangeListener;
3031
import com.clickhouse.config.ClickHouseOption;
3132
import com.clickhouse.data.ClickHouseChecker;
@@ -590,7 +591,13 @@ public ClickHouseConfig getConfig() {
590591
Map<ClickHouseOption, Serializable> merged = new HashMap<>();
591592
merged.putAll(clientConfig.getAllOptions());
592593
merged.putAll(options);
593-
config = new ClickHouseConfig(merged, node.getCredentials(clientConfig),
594+
595+
ClickHouseCredentials credentials = node.getCredentials(clientConfig);
596+
if (merged.containsKey(ClickHouseDefaults.USER) && merged.containsKey(ClickHouseDefaults.PASSWORD)) {
597+
credentials = ClickHouseCredentials.fromUserAndPassword((String) merged.get(ClickHouseDefaults.USER),
598+
(String) merged.get(ClickHouseDefaults.PASSWORD));
599+
}
600+
config = new ClickHouseConfig(merged, credentials,
594601
clientConfig.getNodeSelector(), clientConfig.getMetricRegistry().orElse(null));
595602
}
596603
}

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,9 @@ public static ClickHouseNode getClickHouseNode(ClickHouseProtocol protocol, bool
250250
}
251251
}
252252

253-
return ClickHouseNode.builder(template).address(protocol, new InetSocketAddress(host, port)).build();
253+
return ClickHouseNode.builder(template).address(protocol, new InetSocketAddress(host, port))
254+
.credentials(new ClickHouseCredentials("default", getPassword()))
255+
.build();
254256
}
255257

256258
public static ClickHouseNode getClickHouseNode(ClickHouseProtocol protocol, int port) {
@@ -314,7 +316,7 @@ public static String getPassword() {
314316
if (isCloud) {
315317
return System.getenv("CLICKHOUSE_CLOUD_PASSWORD");
316318
} else {
317-
return "";
319+
return "test_default_password";
318320
}
319321
}
320322

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -2511,7 +2511,7 @@ public void testTransactionTimeout() throws ClickHouseException {
25112511

25122512
tx.begin();
25132513
try {
2514-
Thread.sleep(3000L);
2514+
Thread.sleep(4000L);
25152515
} catch (InterruptedException ex) {
25162516
Assert.fail("Sleep was interrupted", ex);
25172517
}
@@ -2706,6 +2706,7 @@ public void testFailover() throws ClickHouseException {
27062706
ClickHouseNode availableNode = getServer();
27072707
Properties props = new Properties();
27082708
props.setProperty("failover", "1");
2709+
props.setProperty(ClickHouseDefaults.PASSWORD.getKey(), getPassword());
27092710

27102711
// nodes with the first node is unavailable
27112712
ClickHouseNodes nodes = ClickHouseNodes.of(

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

+11-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
</managed2>
1111
</profiles>
1212
<users>
13+
<default>
14+
<profile>default</profile>
15+
<networks>
16+
<ip>::/0</ip>
17+
</networks>
18+
<password>test_default_password</password>
19+
<quota>default</quota>
20+
<access_management>1</access_management>
21+
</default>
1322
<dba>
1423
<access_management>1</access_management>
1524
<profile>default</profile>
@@ -40,15 +49,15 @@
4049
<networks>
4150
<ip>::/0</ip>
4251
</networks>
43-
<password></password>
52+
<password>poorman_111</password>
4453
<quota>default</quota>
4554
</poorman1>
4655
<poorman2>
4756
<profile>managed2</profile>
4857
<networks>
4958
<ip>::/0</ip>
5059
</networks>
51-
<password></password>
60+
<password>poorman_222</password>
5261
<quota>default</quota>
5362
</poorman2>
5463
<test>

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

+109-1
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,19 @@
3737

3838
import java.io.Serializable;
3939
import java.lang.reflect.Array;
40+
import java.math.BigInteger;
4041
import java.time.OffsetDateTime;
4142
import java.util.ArrayList;
4243
import java.util.Arrays;
44+
import java.util.Collection;
4345
import java.util.Collections;
46+
import java.util.Comparator;
47+
import java.util.HashMap;
4448
import java.util.LinkedList;
4549
import java.util.List;
50+
import java.util.Map;
4651
import java.util.Objects;
52+
import java.util.Set;
4753
import java.util.TimeZone;
4854

4955
/**
@@ -65,6 +71,7 @@ public final class ClickHouseColumn implements Serializable {
6571
private static final String KEYWORD_OBJECT = ClickHouseDataType.Object.name();
6672
private static final String KEYWORD_MAP = ClickHouseDataType.Map.name();
6773
private static final String KEYWORD_NESTED = ClickHouseDataType.Nested.name();
74+
private static final String KEYWORD_VARIANT = ClickHouseDataType.Variant.name();
6875

6976
private int columnCount;
7077
private int columnIndex;
@@ -92,6 +99,14 @@ public final class ClickHouseColumn implements Serializable {
9299

93100
private ClickHouseValue template;
94101

102+
private Map<Class<?>, Integer> classToVariantOrdNumMap;
103+
104+
private Map<Class<?>, Integer> arrayToVariantOrdNumMap;
105+
106+
private Map<Class<?>, Integer> mapKeyToVariantOrdNumMap;
107+
private Map<Class<?>, Integer> mapValueToVariantOrdNumMap;
108+
109+
95110
private static ClickHouseColumn update(ClickHouseColumn column) {
96111
column.enumConstants = ClickHouseEnum.EMPTY;
97112
int size = column.parameters.size();
@@ -273,6 +288,9 @@ private static ClickHouseColumn update(ClickHouseColumn column) {
273288
case Nothing:
274289
column.template = ClickHouseEmptyValue.INSTANCE;
275290
break;
291+
case Variant:
292+
column.template = ClickHouseTupleValue.of();
293+
break;
276294
default:
277295
break;
278296
}
@@ -398,7 +416,8 @@ protected static int readColumn(String args, int startIndex, int len, String nam
398416
fixedLength = false;
399417
estimatedLength++;
400418
} else if (args.startsWith(matchedKeyword = KEYWORD_TUPLE, i)
401-
|| args.startsWith(matchedKeyword = KEYWORD_OBJECT, i)) {
419+
|| args.startsWith(matchedKeyword = KEYWORD_OBJECT, i)
420+
|| args.startsWith(matchedKeyword = KEYWORD_VARIANT, i)) {
402421
int index = args.indexOf('(', i + matchedKeyword.length());
403422
if (index < i) {
404423
throw new IllegalArgumentException(ERROR_MISSING_NESTED_TYPE);
@@ -410,12 +429,22 @@ protected static int readColumn(String args, int startIndex, int len, String nam
410429
if (c == ')') {
411430
break;
412431
} else if (c != ',' && !Character.isWhitespace(c)) {
432+
String columnName = "";
413433
i = readColumn(args, i, endIndex, "", nestedColumns);
414434
}
415435
}
416436
if (nestedColumns.isEmpty()) {
417437
throw new IllegalArgumentException("Tuple should have at least one nested column");
418438
}
439+
440+
List<ClickHouseDataType> variantDataTypes = new ArrayList<>();
441+
if (matchedKeyword.equals(KEYWORD_VARIANT)) {
442+
nestedColumns.sort(Comparator.comparing(o -> o.getDataType().name()));
443+
nestedColumns.forEach(c -> {
444+
c.columnName = "v." + c.getDataType().name();
445+
variantDataTypes.add(c.dataType);
446+
});
447+
}
419448
column = new ClickHouseColumn(ClickHouseDataType.valueOf(matchedKeyword), name,
420449
args.substring(startIndex, endIndex + 1), nullable, lowCardinality, null, nestedColumns);
421450
for (ClickHouseColumn n : nestedColumns) {
@@ -424,6 +453,39 @@ protected static int readColumn(String args, int startIndex, int len, String nam
424453
fixedLength = false;
425454
}
426455
}
456+
column.classToVariantOrdNumMap = ClickHouseDataType.buildVariantMapping(variantDataTypes);
457+
458+
for (int ordNum = 0; ordNum < nestedColumns.size(); ordNum++) {
459+
ClickHouseColumn nestedColumn = nestedColumns.get(ordNum);
460+
if (nestedColumn.getDataType() == ClickHouseDataType.Array) {
461+
Set<Class<?>> classSet = ClickHouseDataType.DATA_TYPE_TO_CLASS.get(nestedColumn.arrayBaseColumn.dataType);
462+
if (classSet != null) {
463+
if (column.arrayToVariantOrdNumMap == null) {
464+
column.arrayToVariantOrdNumMap = new HashMap<>();
465+
}
466+
for (Class<?> c : classSet) {
467+
column.arrayToVariantOrdNumMap.put(c, ordNum);
468+
}
469+
}
470+
} else if (nestedColumn.getDataType() == ClickHouseDataType.Map) {
471+
Set<Class<?>> keyClassSet = ClickHouseDataType.DATA_TYPE_TO_CLASS.get(nestedColumn.getKeyInfo().getDataType());
472+
Set<Class<?>> valueClassSet = ClickHouseDataType.DATA_TYPE_TO_CLASS.get(nestedColumn.getValueInfo().getDataType());
473+
if (keyClassSet != null && valueClassSet != null) {
474+
if (column.mapKeyToVariantOrdNumMap == null) {
475+
column.mapKeyToVariantOrdNumMap = new HashMap<>();
476+
}
477+
if (column.mapValueToVariantOrdNumMap == null) {
478+
column.mapValueToVariantOrdNumMap = new HashMap<>();
479+
}
480+
for (Class<?> c : keyClassSet) {
481+
column.mapKeyToVariantOrdNumMap.put(c, ordNum);
482+
}
483+
for (Class<?> c : valueClassSet) {
484+
column.mapValueToVariantOrdNumMap.put(c, ordNum);
485+
}
486+
}
487+
}
488+
}
427489
}
428490

429491
if (column == null) {
@@ -627,6 +689,52 @@ public boolean isAggregateFunction() {
627689

628690
}
629691

692+
public int getVariantOrdNum(Object value) {
693+
if (value != null && value.getClass().isArray()) {
694+
// TODO: add cache by value class
695+
Class<?> c = value.getClass();
696+
while (c.isArray()) {
697+
c = c.getComponentType();
698+
}
699+
return arrayToVariantOrdNumMap.getOrDefault(c, -1);
700+
} else if (value != null && value instanceof List<?>) {
701+
// TODO: add cache by instance of the list
702+
Object tmpV = ((List) value).get(0);
703+
Class<?> valueClass = tmpV.getClass();
704+
while (tmpV instanceof List<?>) {
705+
tmpV = ((List) tmpV).get(0);
706+
valueClass = tmpV.getClass();
707+
}
708+
return arrayToVariantOrdNumMap.getOrDefault(valueClass, -1);
709+
} else if (value != null && value instanceof Map<?,?>) {
710+
// TODO: add cache by instance of map
711+
Map<?, ?> map = (Map<?, ?>) value;
712+
if (!map.isEmpty()) {
713+
for (Map.Entry<?, ?> e : map.entrySet()) {
714+
if (e.getValue() != null) {
715+
int keyOrdNum = mapKeyToVariantOrdNumMap.getOrDefault(e.getKey().getClass(), -1);
716+
int valueOrdNum = mapValueToVariantOrdNumMap.getOrDefault(e.getValue().getClass(), -1);
717+
718+
if (keyOrdNum == valueOrdNum) {
719+
return valueOrdNum; // exact match
720+
} else if (keyOrdNum != -1 && valueOrdNum != -1) {
721+
if (ClickHouseDataType.DATA_TYPE_TO_CLASS.get(nested.get(keyOrdNum).getValueInfo().getDataType()).contains(e.getValue().getClass())){
722+
return keyOrdNum; // can write to map found by key class because values are compatible
723+
} else {
724+
return valueOrdNum;
725+
}
726+
}
727+
728+
break;
729+
}
730+
}
731+
}
732+
return -1;
733+
} else {
734+
return classToVariantOrdNumMap.getOrDefault(value.getClass(), -1);
735+
}
736+
}
737+
630738
public boolean isArray() {
631739
return dataType == ClickHouseDataType.Array;
632740
}

0 commit comments

Comments
 (0)