Skip to content

[client-v2, jdbc-v2] Makes 159 Execution TImeout not retriable & make setQueryTimeout set proper setting. - #3073

Merged
chernser merged 5 commits into
v0.9.9from
08/24/26/set_query_timeout_patch_0.9.9
Aug 25, 2026
Merged

chernser merged 5 commits into
v0.9.9from
08/24/26/set_query_timeout_patch_0.9.9

Conversation

@chernser

@chernser chernser commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Makes server error 159 Execution Timeout not retriable
  • Backports some test fixes from 0.10.0
  • Adds test for JDBC that verifies setQueryTimeout() works when client uses async operations
  • Makes Statement#setQueryTimeout modify request settings and setting max_execution_time. This happens only if non async mode used for client

Closes: #3074

Checklist

Delete items not relevant to your PR:

  • Closes #
  • Unit and integration tests covering the common scenarios were added
  • A human-readable description of the changes was provided to include in CHANGELOG
  • For significant changes, documentation in https://github.com/ClickHouse/clickhouse-docs was updated with further explanations or tutorials

…e fixes for tests. Added test for JDBC driver with sync=1
@chernser
chernser requested a review from mzitnik as a code owner August 24, 2026 22:08
Comment thread client-v2/src/test/java/com/clickhouse/client/ClientTests.java
Comment thread jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java
Comment thread jdbc-v2/src/main/java/com/clickhouse/jdbc/StatementImpl.java

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts timeout/error handling in the client-v2 and JDBC-v2 layers so that ClickHouse server error 159 (Execution Timeout) is no longer treated as retryable, and adds/updates integration tests to validate query timeout behavior (including when JDBC uses async operations).

Changes:

  • client-v2: Mark ServerException code 159 as non-retryable and add a named constant for it.
  • jdbc-v2: Translate execution-timeout conditions into SQLTimeoutException and add new integration tests validating Statement.setQueryTimeout() behavior for async and server-side timeouts.
  • Tests/fixtures: Update SQL/YAML expectations and float boundary assertions; improve metrics pool test concurrency behavior.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
jdbc-v2/src/test/resources/StatementSQLTests.yaml Updates EXPLAIN query variant and expected row count.
jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java Adds query-timeout tests (async + server max_execution_time).
jdbc-v2/src/test/java/com/clickhouse/jdbc/JdbcDataTypeTests.java Stabilizes Float32 boundary assertions.
jdbc-v2/src/main/java/com/clickhouse/jdbc/StatementImpl.java Maps execution timeout to SQLTimeoutException.
jdbc-v2/src/main/java/com/clickhouse/jdbc/metadata/DatabaseMetaDataImpl.java Extends engine-to-table-type mapping (new engines).
jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/parser/javacc/ClickHouseSqlUtils.java Adds newer keyword aliases.
client-v2/src/test/java/com/clickhouse/client/query/QueryTests.java Adjusts float expectations based on server version behavior.
client-v2/src/test/java/com/clickhouse/client/metrics/MetricsTest.java Makes metrics pool concurrency assertions more deterministic.
client-v2/src/test/java/com/clickhouse/client/ClientTests.java Adds execution-timeout test for server setting.
client-v2/src/main/java/com/clickhouse/client/api/ServerException.java Adds EXECUTION_TIMEOUT constant and removes 159 from retryable codes.
clickhouse-jdbc/src/test/java/com/clickhouse/jdbc/GenericJDBCTest.java Disables one test pending follow-up.
CHANGELOG.md Adds changelog entry for non-retryable 159 behavior.
Suppressed comments (5)

jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java:400

  • The assertion compares runtime against queryTimeoutMs, but the configured timeout is in whole seconds (setQueryTimeout(int seconds)). This mismatch can cause flaky assertions (e.g. 3s timeout vs 3.7s queryTimeoutMs).
                long wTimeoutTime = System.currentTimeMillis() - wTimeoutStart;
                assertTrue(Math.abs(wTimeoutTime - queryTimeoutMs) < 1000);

jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java:425

  • max_execution_time is configured in seconds, but the test computes queryTimeoutMs and truncates it to seconds. If it truncates to 0, the server timeout is effectively disabled and the test can pass/fail depending on environment speed. Consider clamping to at least 1 second and asserting against the effective seconds-based timeout instead of millisecond target.
        int queryTimeoutMs = (int) (woTimeoutTime * 0.75);
        Properties config = new Properties();
        config.setProperty(ClientConfigProperties.serverSetting("max_execution_time"), String.valueOf(TimeUnit.MILLISECONDS.toSeconds(queryTimeoutMs)));
        try (Connection conn = getJdbcConnection(config)) {

jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java:438

  • This assertion compares elapsed time to queryTimeoutMs (a millisecond value), but max_execution_time is set in whole seconds (truncated). As a result, the effective timeout can be significantly lower than queryTimeoutMs, making the assertion flaky.
                long wTimeoutTime = System.currentTimeMillis() - wTimeoutStart;
                assertTrue(Math.abs(wTimeoutTime - queryTimeoutMs) < 1000);

jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java:446

  • The async max_execution_time configuration repeats the same milliseconds-to-seconds truncation; if it truncates to 0, the server-side timeout is disabled for this part of the test.
        config = new Properties();
        config.setProperty(ClientConfigProperties.serverSetting("max_execution_time"), String.valueOf(TimeUnit.MILLISECONDS.toSeconds(queryTimeoutMs)));
        config.setProperty(ClientConfigProperties.ASYNC_OPERATIONS.getKey(), "true");
        try (Connection conn = getJdbcConnection(config)) {

jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java:459

  • Same as the non-async branch: the assertion uses queryTimeoutMs while the configured max_execution_time is in whole seconds (possibly truncated). This can make the runtime check brittle.
                long wTimeoutTime = System.currentTimeMillis() - wTimeoutStart;
                assertTrue(Math.abs(wTimeoutTime - queryTimeoutMs) < 1000);

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread jdbc-v2/src/main/java/com/clickhouse/jdbc/StatementImpl.java
Comment thread client-v2/src/test/java/com/clickhouse/client/ClientTests.java
Comment thread jdbc-v2/src/test/java/com/clickhouse/jdbc/StatementTest.java
Comment thread CHANGELOG.md Outdated
@chernser chernser changed the title [client-v2, jdbc-v2] Makes 159 Execution TImeout not retriable [client-v2, jdbc-v2] Makes 159 Execution TImeout not retriable & make setQueryTimeout set proper setting. Aug 25, 2026
@chernser

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 60bb7e1. Configure here.

Comment thread jdbc-v2/src/main/java/com/clickhouse/jdbc/StatementImpl.java
@chernser
chernser merged commit 2ac7e11 into v0.9.9 Aug 25, 2026
18 of 20 checks passed
nicolasblaye pushed a commit to nicolasblaye/clickhouse-jdbc that referenced this pull request Sep 18, 2026
…ur setQueryTimeout

Ports the 0.9.9 patch (ClickHouse#3073) to main. The patch was merged into the v0.9.9
maintenance branch only, so 0.10.0 and main carry the original behaviour.

- client-v2: `ServerException` no longer reports code 159 TIMEOUT_EXCEEDED as
  retryable. The server raises it once the query has already consumed its whole
  `max_execution_time` budget, so an automatic retry spends that budget again.
- jdbc-v2: `Statement#setQueryTimeout` is applied as the `max_execution_time`
  server setting when asynchronous operations are disabled, because the query
  then runs in the calling thread and a future timeout cannot interrupt it. A
  negative value is rejected; zero clears the setting.
- jdbc-v2: an execution timeout is reported as `SQLTimeoutException`.

Two deliberate differences from the 0.9.9 patch:

- `SQLTimeoutException` carries the ClickHouse error code as its vendor code,
  matching what `ExceptionUtils.toSqlState` already does for `ServerException`.
  The 0.9.9 patch used the `(String, Throwable)` constructor, which leaves
  `getErrorCode()` at 0, so callers that classify on the vendor code had to walk
  the cause chain.
- The `ConnectionImpl` hunk and the `connectionLvlExecTimeout` field are left
  out. They exist to restore a connection-level `max_execution_time` on
  `setQueryTimeout(0)`; on main the same result comes from resetting the option
  and falling back to the client configuration. The part of that hunk that makes
  the documented `default_query_settings` property take effect is a separate bug
  and belongs in its own change.

`HttpAPIClientHelperTest.serverExceptionRetryCases` used 159 as its example of a
retryable code. The test covers `shouldRetry` reading the `ServerException` from
the cause instead of throwing `ClassCastException`, so it now uses 209
SOCKET_TIMEOUT and its intent is unchanged.

The unrelated backports carried by ClickHouse#3073 (ClickHouseSqlUtils keywords,
DatabaseMetaDataImpl engine map, test stabilisation) are already on main.

Closes ClickHouse#3136

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants