@Override
    public CompletableFuture<ClickHouseResponse> execute(ClickHouseRequest<?> request) {
        final long start = System.nanoTime();
        // sealedRequest is an immutable copy of the original request
        final ClickHouseRequest<?> sealedRequest = request.seal();

        if (sealedRequest.getConfig().isAsync()) {
            final Object[] args = getAsyncExecArguments(sealedRequest);
            return CompletableFuture.supplyAsync(() -> {
                try {
                    return sendAsync(sealedRequest, args);
                } catch (ClickHouseException | IOException e) {
                    throw new CompletionException(ClickHouseException.of(e, sealedRequest.getServer()));
                } finally {
                    if (measureRequestTime) {
                        long elapsed = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
                        if (elapsed > 1000) {
                            log.info("Request took long to execute: %s", elapsed);
                        }
                    }
                }
            }, getExecutor());
        } else {
            try {
                return CompletableFuture.completedFuture(send(sealedRequest));
            } catch (ClickHouseException | IOException e) {
                return failedResponse(ClickHouseException.of(e, sealedRequest.getServer()));
            } finally {
                if (measureRequestTime) {
                    long elapsed = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
                    if (elapsed > 1000) {
                        log.info("Request took long to execute: %s", elapsed);
                    }
                }
            }
        }
    }
Gets a connection according to the given request.

@param request non-null request
@return non-null connection
@throws CompletionException when error occured
clickhouse-client/src/main/java/com/clickhouse/client/AbstractClient.java