Skip to content

Commit 8f5420e

Browse files
authored
Merge branch 'main' into datagrip-issues
2 parents 97ff164 + fe7ff4d commit 8f5420e

File tree

23 files changed

+574
-162
lines changed

23 files changed

+574
-162
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
### New Features
44
- Added basic auth support for proxies. Now you can specify username/password when connecting via a proxy that requires it with HttpURLConnection and Apache HttpClient.
55

6+
### Bug Fixes
7+
- Fix for retrying on `ConnectTimeoutException`
8+
69
## 0.7.1-patch1
710

811
### Bug Fixes

client-v2/src/main/java/com/clickhouse/client/api/Client.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import java.io.InputStream;
6464
import java.lang.reflect.InvocationTargetException;
6565
import java.lang.reflect.Method;
66+
import java.net.ConnectException;
6667
import java.net.URL;
6768
import java.nio.charset.StandardCharsets;
6869
import java.time.Duration;
@@ -209,6 +210,10 @@ public void close() {
209210
if (oldClient != null) {
210211
oldClient.close();
211212
}
213+
214+
if (httpClientHelper != null) {
215+
httpClientHelper.close();
216+
}
212217
}
213218

214219
public static class Builder {
@@ -290,7 +295,7 @@ public Builder addEndpoint(String endpoint) {
290295
throw new IllegalArgumentException("Only HTTP and HTTPS protocols are supported");
291296
}
292297
} catch (java.net.MalformedURLException e) {
293-
throw new IllegalArgumentException("Endpoint should be a valid URL string", e);
298+
throw new IllegalArgumentException("Endpoint should be a valid URL string, but was " + endpoint, e);
294299
}
295300
return this;
296301
}
@@ -940,6 +945,16 @@ public Builder setClientName(String clientName) {
940945
return this;
941946
}
942947

948+
/**
949+
* Sets client options from provided map. Values are copied as is
950+
* @param options - map of client options
951+
* @return same instance of the builder
952+
*/
953+
public Builder setOptions(Map<String, String> options) {
954+
this.configuration.putAll(options);
955+
return this;
956+
}
957+
943958
public Client build() {
944959
setDefaults();
945960

@@ -950,7 +965,7 @@ public Client build() {
950965
// check if username and password are empty. so can not initiate client?
951966
if (!this.configuration.containsKey("access_token") &&
952967
(!this.configuration.containsKey("user") || !this.configuration.containsKey("password")) &&
953-
!MapUtils.getFlag(this.configuration, "ssl_authentication")) {
968+
!MapUtils.getFlag(this.configuration, "ssl_authentication", false)) {
954969
throw new IllegalArgumentException("Username and password (or access token, or SSL authentication) are required");
955970
}
956971

@@ -1394,7 +1409,7 @@ public CompletableFuture<InsertResponse> insert(String tableName, List<?> data,
13941409
metrics.operationComplete();
13951410
metrics.setQueryId(queryId);
13961411
return new InsertResponse(metrics);
1397-
} catch ( NoHttpResponseException | ConnectionRequestTimeoutException | ConnectTimeoutException e) {
1412+
} catch (NoHttpResponseException | ConnectionRequestTimeoutException | ConnectTimeoutException | ConnectException e) {
13981413
lastException = httpClientHelper.wrapException("Insert request initiation failed", e);
13991414
if (httpClientHelper.shouldRetry(e, finalSettings.getAllSettings())) {
14001415
LOG.warn("Retrying", e);
@@ -1522,7 +1537,7 @@ public CompletableFuture<InsertResponse> insert(String tableName,
15221537
metrics.operationComplete();
15231538
metrics.setQueryId(queryId);
15241539
return new InsertResponse(metrics);
1525-
} catch ( NoHttpResponseException | ConnectionRequestTimeoutException | ConnectTimeoutException e) {
1540+
} catch (NoHttpResponseException | ConnectionRequestTimeoutException | ConnectTimeoutException | ConnectException e) {
15261541
lastException = httpClientHelper.wrapException("Insert request initiation failed", e);
15271542
if (httpClientHelper.shouldRetry(e, finalSettings.getAllSettings())) {
15281543
LOG.warn("Retrying", e);
@@ -1688,7 +1703,7 @@ public CompletableFuture<QueryResponse> query(String sqlQuery, Map<String, Objec
16881703

16891704
return new QueryResponse(httpResponse, finalSettings.getFormat(), finalSettings, metrics);
16901705

1691-
} catch ( NoHttpResponseException | ConnectionRequestTimeoutException | ConnectTimeoutException e) {
1706+
} catch (NoHttpResponseException | ConnectionRequestTimeoutException | ConnectTimeoutException | ConnectException e) {
16921707
lastException = httpClientHelper.wrapException("Query request initiation failed", e);
16931708
if (httpClientHelper.shouldRetry(e, finalSettings.getAllSettings())) {
16941709
LOG.warn("Retrying.", e);
@@ -2105,6 +2120,10 @@ public Set<String> getEndpoints() {
21052120
return Collections.unmodifiableSet(endpoints);
21062121
}
21072122

2123+
public String getUser() {
2124+
return this.configuration.get(ClientConfigProperties.USER.getKey());
2125+
}
2126+
21082127
/**
21092128
* Sets list of DB roles that should be applied to each query.
21102129
*

client-v2/src/main/java/com/clickhouse/client/api/ClientConfigProperties.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ public enum ClientConfigProperties {
1717

1818
HTTP_USE_BASIC_AUTH("http_use_basic_auth"),
1919

20-
USER("user"),
20+
USER("user", "default"),
2121

22-
PASSWORD("password"),
22+
PASSWORD("password", ""),
2323

2424
/**
2525
* Maximum number of active connection in internal connection pool.
2626
*/
27-
HTTP_MAX_OPEN_CONNECTIONS("max_open_connections"),
27+
HTTP_MAX_OPEN_CONNECTIONS("max_open_connections", "10"),
2828

2929
/**
3030
* HTTP keep-alive timeout override.
@@ -59,7 +59,7 @@ public enum ClientConfigProperties {
5959

6060
SOCKET_LINGER_OPT("socket_linger"),
6161

62-
DATABASE("database"),
62+
DATABASE("database", "default"),
6363

6464
COMPRESS_SERVER_RESPONSE("compress"), // actually a server setting, but has client effect too
6565

@@ -118,14 +118,37 @@ public enum ClientConfigProperties {
118118

119119
private String key;
120120

121+
private String defaultValue;
122+
123+
private List<String> choices;
124+
125+
121126
ClientConfigProperties(String key) {
127+
this(key, null, Collections.emptyList());
128+
}
129+
130+
ClientConfigProperties(String key, String defaultValue) {
131+
this(key, defaultValue, Collections.emptyList());
132+
}
133+
134+
ClientConfigProperties(String key, String defaultValue, List<String> choices) {
122135
this.key = key;
136+
this.defaultValue = defaultValue;
137+
this.choices = Collections.unmodifiableList(choices);
123138
}
124139

125140
public String getKey() {
126141
return key;
127142
}
128143

144+
public List<String> getChoices() {
145+
return choices;
146+
}
147+
148+
public String getDefaultValue() {
149+
return defaultValue;
150+
}
151+
129152
public static final String HTTP_HEADER_PREFIX = "http_header_";
130153

131154
public static final String SERVER_SETTING_PREFIX = "clickhouse_setting_";

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

Lines changed: 2 additions & 0 deletions
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:
@@ -518,6 +519,7 @@ public boolean hasValue(int colIndex) {
518519

519520
@Override
520521
public boolean hasValue(String colName) {
522+
getSchema().getColumnByName(colName);
521523
return currentRecord.containsKey(colName);
522524
}
523525

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/main/java/com/clickhouse/client/api/internal/HttpAPIClientHelper.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.apache.hc.core5.http.impl.io.DefaultHttpResponseParserFactory;
4343
import org.apache.hc.core5.http.io.SocketConfig;
4444
import org.apache.hc.core5.http.io.entity.EntityTemplate;
45+
import org.apache.hc.core5.io.CloseMode;
4546
import org.apache.hc.core5.io.IOCallback;
4647
import org.apache.hc.core5.net.URIBuilder;
4748
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
@@ -582,7 +583,7 @@ public boolean shouldRetry(Exception ex, Map<String, Object> requestSettings) {
582583
return retryCauses.contains(ClientFaultCause.NoHttpResponse);
583584
}
584585

585-
if (ex instanceof ConnectException) {
586+
if (ex instanceof ConnectException || ex instanceof ConnectTimeoutException) {
586587
return retryCauses.contains(ClientFaultCause.ConnectTimeout);
587588
}
588589

@@ -597,6 +598,7 @@ public boolean shouldRetry(Exception ex, Map<String, Object> requestSettings) {
597598
// ClientException will be also wrapped
598599
public ClientException wrapException(String message, Exception cause) {
599600
if (cause instanceof ConnectionRequestTimeoutException ||
601+
cause instanceof NoHttpResponseException ||
600602
cause instanceof ConnectTimeoutException ||
601603
cause instanceof ConnectException) {
602604
return new ConnectionInitiationException(message, cause);
@@ -639,4 +641,8 @@ public static Map<String, String> parseUrlParameters(URL url) {
639641

640642
return params;
641643
}
644+
645+
public void close() {
646+
httpClient.close(CloseMode.IMMEDIATE);
647+
}
642648
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,14 @@ public final class ServerSettings {
2222
*/
2323
public static final String OUTPUT_FORMAT_BINARY_WRITE_JSON_AS_STRING = "output_format_binary_write_json_as_string";
2424

25+
/**
26+
* Limit number of rows in a result set
27+
*/
28+
public static final String MAX_RESULT_ROWS = "max_result_rows";
29+
30+
/**
31+
* Defines server response if result set exceeded a limit set by {@code max_result_rows}.
32+
* Possible values are 'throw' or 'break'. Default is 'throw'
33+
*/
34+
public static final String RESULT_OVERFLOW_MODE = "result_overflow_mode";
2535
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.clickhouse.client.api.metadata;
2+
3+
import com.clickhouse.client.api.ClientException;
4+
5+
public class NoSuchColumnException extends ClientException {
6+
7+
public NoSuchColumnException(String message) {
8+
super(message);
9+
}
10+
}

client-v2/src/main/java/com/clickhouse/client/api/metadata/TableSchema.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.clickhouse.client.api.metadata;
22

3+
import com.clickhouse.client.api.ClientException;
34
import com.clickhouse.data.ClickHouseColumn;
45

56
import java.util.ArrayList;
@@ -87,20 +88,22 @@ public void addColumn(String name, String type, String defaultType) {
8788
}
8889

8990
public ClickHouseColumn getColumnByName(String name) {
90-
for (ClickHouseColumn column : columns) {
91-
if (column.getColumnName().equalsIgnoreCase(name)) {
92-
return column;//TODO: Try to deep clone the column rather than reference pass
93-
}
94-
}
95-
96-
return null;
91+
return columns.get(nameToIndex(name));
9792
}
9893

9994
public String indexToName(int index) {
100-
return columns.get(index).getColumnName();
95+
try {
96+
return columns.get(index).getColumnName();
97+
} catch (IndexOutOfBoundsException e) {
98+
throw new NoSuchColumnException("Result has no column with index = " + index);
99+
}
101100
}
102101

103102
public int nameToIndex(String name) {
103+
Integer index = colIndex.get(name);
104+
if (index == null) {
105+
throw new NoSuchColumnException("Result has no column with name '" + name + "'");
106+
}
104107
return colIndex.get(name).intValue();
105108
}
106109

0 commit comments

Comments
 (0)