Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 113 additions & 16 deletions CHANGELOG.md

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions build_examples.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
LIB_VER=$(grep '<revision>' pom.xml | sed -e 's|[[:space:]]*<[/]*revision>[[:space:]]*||g')
find `pwd`/examples -type f -name pom.xml -exec sed -i -e "s|\(<clickhouse-java.version>\).*\(<\)|\1$LIB_VER\2|g" {} \;
Comment thread
chernser marked this conversation as resolved.
for d in $(ls -d `pwd`/examples/*/); do \
if [ -e $d/pom.xml ]; then cd $d && mvn --batch-mode --no-transfer-progress clean compile; fi;
if [ -e $d/gradlew ]; then cd $d && ./gradlew clean build; fi;
done
Comment thread
chernser marked this conversation as resolved.
Comment thread
chernser marked this conversation as resolved.

85 changes: 85 additions & 0 deletions docs/releases/0_10_0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Release 0.10.0

# Migration Guide

## JDBC-V2: `async_insert=1` not Set by Default

The previous version of the JDBC driver set `async_insert=0`, effectively making any insert operation synchronous.
This was done to get the insert summary that is then returned by the family of `java.sql.Statement#executeUpdate(java.lang.String)` methods.
Now these methods will not return an accurate number of records (in most cases `0`) if the server is using `async_insert=1`.

Set `clickhouse_setting_wait_for_async_insert=1` at the connection level to make the server wait for the async insert to complete. In this
case the client will get a response and return control once the operation is done on the server side. However, this option does not produce an accurate summary.

Set `clickhouse_setting_async_insert=0` at the connection level (or pass it via the JDBC connection string) to fall back to synchronous inserts.

See more about async inserts: https://clickhouse.com/docs/optimize/asynchronous-inserts

## CLIENT-V2 & JDBC-V2: User/Password Credentials not Allowed with Custom `Authorization` HTTP Header

The client builder throws an exception if both user credentials and a custom `Authorization` header are set. This is done to prevent configuration
errors. Previously this combination was accepted and the custom `Authorization` header overrode the user/password at request time.

If an application wants to use both mechanisms, we recommend creating separate Client instances for each authentication method. This will
also protect against using the default user credentials instead of the custom `Authorization` header.


## CLIENT-V2 & JDBC-V2: Access Token and Bearer Token Clarification

There are two configuration parameters:
- `com.clickhouse.client.api.ClientConfigProperties#ACCESS_TOKEN` - accepts a raw value and passes it to the `Authorization` HTTP header.
- `com.clickhouse.client.api.ClientConfigProperties#BEARERTOKEN_AUTH` - adds `Bearer ` before the passed value and writes it to the `Authorization` HTTP header.

The previous version had an issue that made the client ignore `ACCESS_TOKEN`. This is now fixed, and its value is passed to the `Authorization` HTTP header as is.
`com.clickhouse.client.api.ClientConfigProperties#BEARERTOKEN_AUTH` is processed as an alias to `com.clickhouse.client.api.Client.Builder#useBearerTokenAuth`,
which sets `com.clickhouse.client.api.ClientConfigProperties#ACCESS_TOKEN` to `Bearer ` + `token`.

In most cases `com.clickhouse.client.api.ClientConfigProperties#BEARERTOKEN_AUTH` works better because it adds `Bearer `, so there is no need to do it in the application.


## CLIENT-V2 & JDBC-V2: `ClientConfigProperties.MAX_EXECUTION_TIME` (`executionTimeout`) is Always Treated in Milliseconds now

There was a bug where the `executionTimeout` parameter was set in milliseconds but read in seconds. So it caused a bigger timeout than expected.

If your application uses a workaround by setting lower values, then you need to adjust it before migrating to the new version.

See also https://github.com/ClickHouse/clickhouse-java/pull/2841/changes.

## CLIENT-V2 & JDBC-V2: SSLMode (`ssl_mode`) Changes

There was an `ssl_mode` setting with two possible values, `none` and `strict`. It was ignored in V2 for a long time, until now we are re-introducing it.

The most important change is that V1's `none` maps to `TRUST` in the V2 client and driver because it matches the trust-all logic. There was a problem enabling encryption
with self-signed certificates. `none` is still supported by JDBC (only) and is an alias for `TRUST`. Please migrate to the new value.

The V2 client and driver now support these values:
- `DISABLED` - disables encryption. Do not use it with HTTP. This makes sense only for TCP, where the protocol doesn't provide encryption. HTTP has HTTPS for that.
- `TRUST` - valid for all protocols. Means encryption only.
- `VERIFY_CA` - valid for all protocols. Makes the client verify only the CA signature. No identity verification.
- `STRICT` - valid for all protocols. Default when HTTPS is used. Means complete verification of the server identity.


## JDBC-V2: **Deprecation** of `custom_http_params` and `custom_settings`

We still see usage of `custom_http_params` and `custom_settings`, which comes from V1 of the client and JDBC driver.

Please migrate to using the `com.clickhouse.client.api.ClientConfigProperties#SERVER_SETTING_PREFIX` (`clickhouse_setting_`) prefix because
- it is a more solid way to pass settings with a list of values (we had an issue parsing complex properties when they were used within `custom_http_params`).
- it makes the configuration clearer to understand, as it clearly belongs to server-side settings.


## JDBC-V2: **Deprecation** of `use_server_time_zone_for_dates`

The driver does not apply a timezone to `Date` values anymore, as they have no such information stored in the database.


## JDBC-V2: **Deprecation** of `http_connection_provider`

Driver V2 ignores this setting and uses only the available HTTP client.
There are plans to support other HTTP clients and protocols, but they will be configured a different way.


## JDBC-V2: **Deprecation** of `typeMappings`

This property (not a feature) is deprecated. Please use `com.clickhouse.jdbc.DriverProperties#JDBC_TYPE_MAPPINGS` (`jdbc_type_mappings`) instead.

2 changes: 1 addition & 1 deletion examples/client-v2-json-processors/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>

<clickhouse-java.version>0.9.8-SNAPSHOT</clickhouse-java.version>
<clickhouse-java.version>0.10.0-rc1-SNAPSHOT</clickhouse-java.version>
<jackson.version>2.22.0</jackson.version>
<gson.version>2.14.0</gson.version>
<slf4j.version>2.0.17</slf4j.version>
Expand Down
2 changes: 1 addition & 1 deletion examples/client-v2/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<clickhouse-java.version>0.9.8-SNAPSHOT</clickhouse-java.version>
<clickhouse-java.version>0.10.0-rc1-SNAPSHOT</clickhouse-java.version>

<compiler-plugin.version>3.8.1</compiler-plugin.version>

Expand Down
4 changes: 2 additions & 2 deletions examples/client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<clickhouse-java.version>0.9.8-SNAPSHOT</clickhouse-java.version>
<clickhouse-java.version>0.10.0-rc1-SNAPSHOT</clickhouse-java.version>
<!-- Nightly snapshot version from https://central.sonatype.com/repository/maven-snapshots/or latest from local -->
<!-- <clickhouse-java.version>0.9.8-SNAPSHOT</clickhouse-java.version>-->
<!-- <clickhouse-java.version>0.10.0-rc1-SNAPSHOT</clickhouse-java.version>-->

<apache-httpclient.version>5.2.1</apache-httpclient.version>

Expand Down
2 changes: 1 addition & 1 deletion examples/demo-kotlin-service/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ ktor_version=2.3.12
kotlin_version=2.0.20
logback_version=1.4.14

ch_java_client_version=0.9.8
ch_java_client_version=0.10.0-rc1
2 changes: 1 addition & 1 deletion examples/demo-service/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@

ch_java_client_version=0.9.8
ch_java_client_version=0.10.0-rc1
2 changes: 1 addition & 1 deletion examples/jdbc-v2-json-processors/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>

<clickhouse-java.version>0.9.8-SNAPSHOT</clickhouse-java.version>
<clickhouse-java.version>0.10.0-rc1-SNAPSHOT</clickhouse-java.version>
<jackson.version>2.22.0</jackson.version>
<gson.version>2.14.0</gson.version>
<slf4j.version>2.0.17</slf4j.version>
Expand Down
2 changes: 1 addition & 1 deletion examples/jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<clickhouse-java.version>0.9.8-SNAPSHOT</clickhouse-java.version>
<clickhouse-java.version>0.10.0-rc1-SNAPSHOT</clickhouse-java.version>
<hikaricp.version>4.0.3</hikaricp.version>
<apache-httpclient.version>5.2.1</apache-httpclient.version>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<clickhouse-java.version>0.9.8-SNAPSHOT</clickhouse-java.version>
<clickhouse-java.version>0.10.0-rc1-SNAPSHOT</clickhouse-java.version>
<spring-boot-starter.version>2.7.18</spring-boot-starter.version>
</properties>

Expand Down
103 changes: 103 additions & 0 deletions jdbc-v2/docs/floating-point-precision.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Floating-point precision in jdbc-v2

This note documents how `Float32` and `Float64` values behave when written through the
`jdbc-v2` driver, why a `Float32` value can come back differing by up to one ULP, and how
tests should assert floating-point round-trips.

## Background

`PreparedStatement` parameters in `jdbc-v2` are **not** sent in ClickHouse `RowBinary`
form. Instead the driver serializes each parameter into a **textual SQL literal** and
substitutes it into the statement before sending it to the server
(`com.clickhouse.jdbc.PreparedStatementImpl#encodeObject`).

For numeric primitives there is no dedicated branch, so the value falls through to the
default rendering:

```java
return SQLUtils.escapeSingleQuotes(x.toString());
```

This means:

- `setFloat(i, x)` → `Float.toString(x)` (e.g. `-3.402823E38`)
- `setDouble(i, x)` → `Double.toString(x)` (e.g. `-1.7976931348623157E308`)

`Float.toString` / `Double.toString` produce the *shortest* decimal string that round-trips
back to the **same** value *of that width* (`Float.parseFloat` for a float, `Double.parseDouble`
for a double).

## Why a `Float32` can shift by one ULP

When the server reads a decimal literal into a `Float32` column it parses it as `Float64`
first and then narrows the result to `Float32`. That is a **double rounding**:

```
decimal text -> Float64 (round #1) -> Float32 (round #2)
```

The shortest decimal emitted by `Float.toString` is only guaranteed to round-trip via a
**single** `decimal -> Float32` rounding. Routing it through `Float64` first can land on an
adjacent `Float32` value. The error is bounded by **one ULP** of the `Float32`, and in
practice only shows up for extreme magnitudes where the ULP is large.

Observed example:

| Java value inserted | Text sent | Value read back |
| ------------------- | ------------- | ----------------- |
| `-3.402823E38f` | `-3.402823E38`| `-3.4028229E38f` |

`Float64` columns are **not** affected: the literal is parsed straight to `Float64` with a
single rounding, and `Double.toString` already round-trips exactly through that path.

## Read side

On retrieval the binary reader returns boxed primitives that mirror the column type
(`com.clickhouse.client.api.data_formats.internal.BinaryStreamReader`):

| Column type | `getObject` returns |
| ----------- | ------------------- |
| `Float32` | `java.lang.Float` |
| `Float64` | `java.lang.Double` |

So `ResultSet#getObject("float32")` is a `Float`, and `getObject("float64")` is a `Double`.

## Implications for callers

- A `Float32` written via `setFloat` may read back differing by up to one ULP. If you need
bit-exact `Float32` round-trips, avoid the text path — for example insert through the
`client-v2` binary writer, or store the value in a `Float64` column.
- `Float64` written via `setDouble` round-trips exactly.

## Testing guidance

Floating-point round-trips should not be asserted with exact equality for `Float32`. Use a
one-ULP tolerance for `Float32` and exact equality for `Float64`:

```java
// Float32: allow up to one ULP because of decimal -> Float64 -> Float32 double rounding
assertEquals(rs.getFloat("float32"), expected32, Math.ulp(expected32));

// Float64: exact
assertEquals(rs.getDouble("float64"), Double.valueOf(expected64));
```

The same tolerance applies when comparing the boxed `Float` returned by `getObject`:

```java
Object actual32 = rs.getObject("float32");
assertTrue(actual32 instanceof Float);
assertEquals((float) (Float) actual32, expected32, Math.ulp(expected32));
```

See `com.clickhouse.jdbc.JdbcDataTypeTests#testFloatTypes` for a data-set-driven example
that exercises minimum, maximum, zero, unit, subnormal, constant, and random values.

## Related: ClickHouse Cloud read-after-write

`JdbcDataTypeTests` writes test rows and reads them back. On ClickHouse Cloud, separate
connections may be routed to different replicas, so a value written on one connection is not
guaranteed to be immediately visible to a `SELECT` on another. To keep these tests
deterministic without per-query consistency tuning, perform the write and the verifying read
on the **same** connection. `JdbcIntegrationTest#runQuery(String, Connection)` is provided to
run DDL on that same connection and avoid opening extra ones.
2 changes: 1 addition & 1 deletion performance/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<properties>
<apache.httpclient.version>5.3.1</apache.httpclient.version>
<slf4j.version>2.0.17</slf4j.version>
<ch.jdbc.revision>0.9.8-SNAPSHOT</ch.jdbc.revision>
<ch.jdbc.revision>0.10.0-rc1-SNAPSHOT</ch.jdbc.revision>
<jmh.version>1.37</jmh.version>
<testcontainers.version>2.0.2</testcontainers.version>

Expand Down
14 changes: 9 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@

<developers>
<developer>
<id>zhicwu</id>
<name>Zhichun Wu</name>
<email>zhicwu@gmail.com</email>
<timezone>+8</timezone>
<id>sergey_chernov</id>
<name>Sergey Chernov</name>
<email>sergey.chernov@clickhouse.com</email>
</developer>
<developer>
<id>mzitnik</id>
<name>Mark Zitnik</name>
<email>mark@clickhouse.com</email>
</developer>
</developers>

Expand Down Expand Up @@ -69,7 +73,7 @@
</ciManagement>

<properties>
<revision>0.9.8-SNAPSHOT</revision>
<revision>0.10.0-rc1-SNAPSHOT</revision>
<project.current.year>2026</project.current.year>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
Expand Down
Loading