Skip to content

Commit

Permalink
Merge pull request #867 from zhicwu/prepare-release
Browse files Browse the repository at this point in the history
Prepare release
  • Loading branch information
zhicwu authored Mar 14, 2022
2 parents 9cd3797 + 6977c17 commit 0585961
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 34 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Note: in general, the new driver(v0.3.2) is a few times faster with less memory
<groupId>com.clickhouse</groupId>
<!-- or clickhouse-grpc-client if you prefer gRPC -->
<artifactId>clickhouse-http-client</artifactId>
<version>0.3.2-patch6</version>
<version>0.3.2-patch7</version>
</dependency>
```

Expand Down Expand Up @@ -148,7 +148,7 @@ try (ClickHouseClient client = ClickHouseClient.newInstance(preferredProtocol);
<!-- will stop using ru.yandex.clickhouse starting from 0.4.0 -->
<groupId>com.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.3.2-patch6</version>
<version>0.3.2-patch7</version>
<!-- below is only needed when all you want is a shaded jar -->
<classifier>http</classifier>
<exclusions>
Expand Down
2 changes: 1 addition & 1 deletion clickhouse-benchmark/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<properties>
<legacy-driver.version>0.3.1-patch</legacy-driver.version>
<clickhouse4j-driver.version>1.4.4</clickhouse4j-driver.version>
<native-driver.version>2.6.4</native-driver.version>
<native-driver.version>2.6.5</native-driver.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jmh.version>1.34</jmh.version>
<shade.name>benchmarks</shade.name>
Expand Down
2 changes: 1 addition & 1 deletion clickhouse-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Async Java client for ClickHouse. `clickhouse-client` is an abstract module, so
<dependency>
<groupId>com.clickhouse</groupId>
<artifactId>clickhouse-http-client</artifactId>
<version>0.3.2-patch6</version>
<version>0.3.2-patch7</version>
</dependency>
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
Expand Down Expand Up @@ -49,13 +50,12 @@ static ClickHouseClientBuilder builder() {

/**
* Gets default {@link java.util.concurrent.ExecutorService} for static methods
* like {@code dump()}, {@code load()}, {@code send()}, and {@code submit()}
* when {@link com.clickhouse.client.config.ClickHouseDefaults#ASYNC} is
* {@code true}. It will be shared among all client instances when
* like {@code dump()}, {@code load()}, {@code send()}, and {@code submit()}. It
* will be shared among all client instances when
* {@link com.clickhouse.client.config.ClickHouseClientOption#MAX_THREADS_PER_CLIENT}
* is less than or equals to zero.
*
* @return default executor service
* @return non-null default executor service
*/
static ExecutorService getExecutorService() {
return ClickHouseClientBuilder.defaultExecutor;
Expand All @@ -68,7 +68,7 @@ static ExecutorService getExecutorService() {
*
* @param <T> return type of the task
* @param task non-null task
* @return future object to get result
* @return non-null future object to get result
* @throws CompletionException when failed to complete the task
*/
static <T> CompletableFuture<T> submit(Callable<T> task) {
Expand Down Expand Up @@ -114,7 +114,7 @@ static <T> CompletableFuture<T> submit(Callable<T> task) {
* @param format output format to use
* @param compression compression algorithm to use
* @param file output file
* @return future object to get result
* @return non-null future object to get result
* @throws IllegalArgumentException if any of server, tableOrQuery, and output
* is null
* @throws CompletionException when error occurred during execution
Expand Down Expand Up @@ -592,7 +592,8 @@ default boolean accept(ClickHouseProtocol protocol) {
* invoked(usually triggered by {@code request.execute()}).
*
* @param nodeFunc function to get a {@link ClickHouseNode} to connect to
* @return request object holding references to this client and node provider
* @return non-null request object holding references to this client and node
* provider
*/
default ClickHouseRequest<?> connect(Function<ClickHouseNodeSelector, ClickHouseNode> nodeFunc) {
return new ClickHouseRequest<>(this, ClickHouseChecker.nonNull(nodeFunc, "nodeFunc"), false);
Expand All @@ -609,17 +610,47 @@ default ClickHouseRequest<?> connect(Function<ClickHouseNodeSelector, ClickHouse
* execution, meaning you're free to make any change to this
* object(e.g. prepare for next call using different SQL
* statement) without impacting the execution
* @return future object to get result
* @return non-null future object to get result
* @throws CompletionException when error occurred during execution
*/
CompletableFuture<ClickHouseResponse> execute(ClickHouseRequest<?> request);

/**
* Synchronous version of {@link #execute(ClickHouseRequest)}.
*
* @param request request object which will be sealed(immutable copy) upon
* execution
* @return non-null response
* @throws ClickHouseException when error occurred during execution
*/
default ClickHouseResponse executeAndWait(ClickHouseRequest<?> request) throws ClickHouseException {
final ClickHouseRequest<?> sealedRequest = request.seal();

try {
return execute(sealedRequest).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw ClickHouseException.forCancellation(e, sealedRequest.getServer());
} catch (CancellationException e) {
throw ClickHouseException.forCancellation(e, sealedRequest.getServer());
} catch (CompletionException | ExecutionException | UncheckedIOException e) {
Throwable cause = e.getCause();
if (cause == null) {
cause = e;
}
throw cause instanceof ClickHouseException ? (ClickHouseException) cause
: ClickHouseException.of(cause, sealedRequest.getServer());
} catch (RuntimeException e) { // unexpected
throw ClickHouseException.of(e, sealedRequest.getServer());
}
}

/**
* Gets the immutable configuration associated with this client. In most cases
* it's the exact same one passed to {@link #init(ClickHouseConfig)} method for
* initialization.
*
* @return configuration associated with this client
* @return non-null configuration associated with this client
*/
ClickHouseConfig getConfig();

Expand Down Expand Up @@ -650,25 +681,26 @@ default void init(ClickHouseConfig config) {
}

/**
* Tests if the given server is alive or not. Pay attention that it's a
* synchronous call with minimum overhead(e.g. tiny buffer, no compression and
* no deserialization etc).
* Tests if the given server is alive or not. It always returns {@code false}
* when server is {@code null} or timeout is less than one. Pay attention that
* it's a synchronous call with minimum overhead(e.g. tiny buffer, no
* compression and no deserialization etc).
*
* @param server server to test
* @param timeout timeout in millisecond
* @param server non-null server to test
* @param timeout timeout in millisecond, should be greater than zero
* @return true if the server is alive; false otherwise
*/
default boolean ping(ClickHouseNode server, int timeout) {
if (server != null) {
if (server != null && timeout > 0) {
server = ClickHouseCluster.probe(server, timeout);

try (ClickHouseResponse resp = connect(server) // create request
.option(ClickHouseClientOption.ASYNC, false) // use current thread
.option(ClickHouseClientOption.CONNECTION_TIMEOUT, timeout)
.option(ClickHouseClientOption.SOCKET_TIMEOUT, timeout)
.option(ClickHouseClientOption.MAX_BUFFER_SIZE, 8) // actually 4 bytes should be enough
.option(ClickHouseClientOption.MAX_QUEUED_BUFFERS, 1) // enough with only one buffer
.format(ClickHouseFormat.TabSeparated).query("SELECT 1").execute()
.format(ClickHouseFormat.TabSeparated)
.query("SELECT 1 FORMAT TabSeparated").execute()
.get(timeout, TimeUnit.MILLISECONDS)) {
return true;
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public final class ClickHouseColumn implements Serializable {
private int arrayLevel;
private ClickHouseColumn arrayBaseColumn;

private boolean fixedByteLength;
private int estimatedByteLength;

private static ClickHouseColumn update(ClickHouseColumn column) {
column.enumConstants = ClickHouseEnum.EMPTY;
int size = column.parameters.size();
Expand Down Expand Up @@ -70,11 +73,17 @@ private static ClickHouseColumn update(ClickHouseColumn column) {
if (size >= 2) { // same as DateTime64
column.scale = Integer.parseInt(column.parameters.get(0));
column.timeZone = TimeZone.getTimeZone(column.parameters.get(1).replace("'", ""));
if (!column.nullable) {
column.estimatedByteLength += ClickHouseDataType.DateTime64.getByteLength();
}
} else if (size == 1) { // same as DateTime32
// unfortunately this will fall back to GMT if the time zone
// cannot be resolved
TimeZone tz = TimeZone.getTimeZone(column.parameters.get(0).replace("'", ""));
column.timeZone = tz;
if (!column.nullable) {
column.estimatedByteLength += ClickHouseDataType.DateTime32.getByteLength();
}
}
break;
case DateTime32:
Expand All @@ -97,6 +106,18 @@ private static ClickHouseColumn update(ClickHouseColumn column) {
if (size >= 2) {
column.precision = Integer.parseInt(column.parameters.get(0));
column.scale = Integer.parseInt(column.parameters.get(1));

if (!column.nullable) {
if (column.precision > ClickHouseDataType.Decimal128.getMaxScale()) {
column.estimatedByteLength += ClickHouseDataType.Decimal256.getByteLength();
} else if (column.precision > ClickHouseDataType.Decimal64.getMaxScale()) {
column.estimatedByteLength += ClickHouseDataType.Decimal128.getByteLength();
} else if (column.precision > ClickHouseDataType.Decimal32.getMaxScale()) {
column.estimatedByteLength += ClickHouseDataType.Decimal64.getByteLength();
} else {
column.estimatedByteLength += ClickHouseDataType.Decimal32.getByteLength();
}
}
}
break;
case Decimal32:
Expand All @@ -110,6 +131,15 @@ private static ClickHouseColumn update(ClickHouseColumn column) {
case FixedString:
if (size > 0) {
column.precision = Integer.parseInt(column.parameters.get(0));
if (!column.nullable) {
column.estimatedByteLength += column.precision;
}
}
break;
case String:
column.fixedByteLength = false;
if (!column.nullable) {
column.estimatedByteLength += 1;
}
break;
default:
Expand All @@ -129,6 +159,9 @@ protected static int readColumn(String args, int startIndex, int len, String nam
boolean lowCardinality = false;
int i = startIndex;

boolean fixedLength = true;
int estimatedLength = 0;

if (args.startsWith(KEYWORD_LOW_CARDINALITY, i)) {
lowCardinality = true;
int index = args.indexOf('(', i + KEYWORD_LOW_CARDINALITY.length());
Expand Down Expand Up @@ -173,6 +206,8 @@ protected static int readColumn(String args, int startIndex, int len, String nam
column = new ClickHouseColumn(ClickHouseDataType.valueOf(matchedKeyword), name,
args.substring(startIndex, i), nullable, lowCardinality, params, nestedColumns);
column.aggFuncType = aggFunc;
fixedLength = false;
estimatedLength++;
} else if (args.startsWith(KEYWORD_ARRAY, i)) {
int index = args.indexOf('(', i + KEYWORD_ARRAY.length());
if (index < i) {
Expand All @@ -188,6 +223,8 @@ protected static int readColumn(String args, int startIndex, int len, String nam
column = new ClickHouseColumn(ClickHouseDataType.Array, name, args.substring(startIndex, endIndex),
nullable, lowCardinality, null, nestedColumns);
i = endIndex;
fixedLength = false;
estimatedLength++;
} else if (args.startsWith(KEYWORD_MAP, i)) {
int index = args.indexOf('(', i + KEYWORD_MAP.length());
if (index < i) {
Expand All @@ -210,6 +247,8 @@ protected static int readColumn(String args, int startIndex, int len, String nam
column = new ClickHouseColumn(ClickHouseDataType.Map, name, args.substring(startIndex, endIndex), nullable,
lowCardinality, null, nestedColumns);
i = endIndex;
fixedLength = false;
estimatedLength++;
} else if (args.startsWith(KEYWORD_NESTED, i)) {
int index = args.indexOf('(', i + KEYWORD_NESTED.length());
if (index < i) {
Expand All @@ -223,6 +262,8 @@ protected static int readColumn(String args, int startIndex, int len, String nam
}
column = new ClickHouseColumn(ClickHouseDataType.Nested, name, originalTypeName, nullable, lowCardinality,
null, nestedColumns);
fixedLength = false;
estimatedLength++;
} else if (args.startsWith(KEYWORD_TUPLE, i)) {
int index = args.indexOf('(', i + KEYWORD_TUPLE.length());
if (index < i) {
Expand All @@ -243,6 +284,12 @@ protected static int readColumn(String args, int startIndex, int len, String nam
}
column = new ClickHouseColumn(ClickHouseDataType.Tuple, name, args.substring(startIndex, endIndex),
nullable, lowCardinality, null, nestedColumns);
for (ClickHouseColumn n : nestedColumns) {
estimatedLength += n.estimatedByteLength;
if (!n.fixedByteLength) {
fixedLength = false;
}
}
}

if (column == null) {
Expand Down Expand Up @@ -298,6 +345,16 @@ protected static int readColumn(String args, int startIndex, int len, String nam
builder.setLength(0);
}

if (nullable) {
fixedLength = false;
estimatedLength++;
} else if (column.dataType.getByteLength() == 0) {
fixedLength = false;
} else {
estimatedLength += column.dataType.getByteLength();
}
column.fixedByteLength = fixedLength;
column.estimatedByteLength = estimatedLength;
list.add(update(column));

return i;
Expand Down Expand Up @@ -373,11 +430,6 @@ public static List<ClickHouseColumn> parse(String args) {
return Collections.unmodifiableList(c);
}

private ClickHouseColumn(String originalTypeName, String columnName) {
this.originalTypeName = originalTypeName;
this.columnName = columnName;
}

private ClickHouseColumn(ClickHouseDataType dataType, String columnName, String originalTypeName, boolean nullable,
boolean lowCardinality, List<String> parameters, List<ClickHouseColumn> nestedColumns) {
this.aggFuncType = null;
Expand All @@ -403,6 +455,9 @@ private ClickHouseColumn(ClickHouseDataType dataType, String columnName, String
list.addAll(nestedColumns);
this.nested = Collections.unmodifiableList(list);
}

this.fixedByteLength = false;
this.estimatedByteLength = 0;
}

public boolean isAggregateFunction() {
Expand All @@ -420,6 +475,10 @@ public boolean isEnum() {
|| dataType == ClickHouseDataType.Enum16;
}

public boolean isFixedLength() {
return fixedByteLength;
}

public boolean isMap() {
return dataType == ClickHouseDataType.Map;
}
Expand Down Expand Up @@ -448,6 +507,10 @@ public ClickHouseEnum getEnumConstants() {
return enumConstants;
}

public int getEstimatedLength() {
return estimatedByteLength;
}

public String getOriginalTypeName() {
return originalTypeName;
}
Expand Down Expand Up @@ -541,6 +604,8 @@ public int hashCode() {
result = prime * result + precision;
result = prime * result + scale;
result = prime * result + ((timeZone == null) ? 0 : timeZone.hashCode());
result = prime * result + (fixedByteLength ? 1231 : 1237);
result = prime * result + estimatedByteLength;
return result;
}

Expand All @@ -561,7 +626,8 @@ public boolean equals(Object obj) {
&& Objects.equals(nested, other.nested) && nullable == other.nullable
&& Objects.equals(originalTypeName, other.originalTypeName)
&& Objects.equals(parameters, other.parameters) && precision == other.precision && scale == other.scale
&& Objects.equals(timeZone, other.timeZone);
&& Objects.equals(timeZone, other.timeZone) && fixedByteLength == other.fixedByteLength
&& estimatedByteLength == other.estimatedByteLength;
}

@Override
Expand Down
Loading

0 comments on commit 0585961

Please sign in to comment.