Add ClickHouse server-version detection - #293
Conversation
| /* | ||
| * Build the query directly rather than via new_query(): this file does | ||
| * not include fdw.h (which declares chfdw_get_session_settings), and the | ||
| * version probe needs no session settings. | ||
| */ |
There was a problem hiding this comment.
| /* | |
| * Build the query directly rather than via new_query(): this file does | |
| * not include fdw.h (which declares chfdw_get_session_settings), and the | |
| * version probe needs no session settings. | |
| */ |
theory
left a comment
There was a problem hiding this comment.
Will read carefully tomorrow, but just to note here, if we're adding a new SQL function, we need to increment to v0.4.0 and add an upgrade script, sql/pg_clickhouse--0.3--0.4.sql. See #196 for a pervious such change to the extension's catalog.
|
Simpler example of incrementing the version and adding an upgrade script in ClickHouse/pg_re2#22 |
theory
left a comment
There was a problem hiding this comment.
This looks good, though it doesn't look like the http connection caches the version info to allow multiple calls with the same connection without each resulting in an HTTP request.
Please add the new function to pg_clickhouse.md and an item to CHANGELOG.md, as well as the aforementioned migration script and version increments.
Also I thought ClickHouse returned a header with the version, but apparently not:
❯ curl -iX POST 'http://localhost:8123/' -d 'SELECT 1'
HTTP/1.1 200 OK
X-ClickHouse-Summary: {"read_rows":"1","read_bytes":"1","written_rows":"0","written_bytes":"0","total_rows_to_read":"1","result_rows":"0","result_bytes":"0","elapsed_ns":"5185292"}
Date: Wed, 24 Jun 2026 19:58:06 GMT
Connection: Keep-Alive
Content-Type: text/tab-separated-values; charset=UTF-8
Access-Control-Expose-Headers: X-ClickHouse-Query-Id,X-ClickHouse-Summary,X-ClickHouse-Server-Display-Name,X-ClickHouse-Format,X-ClickHouse-Timezone,X-ClickHouse-Exception-Code
X-ClickHouse-Server-Display-Name: clickhouse01
Transfer-Encoding: chunked
X-ClickHouse-Query-Id: 93bf9289-6dbf-4621-a5d9-9c183e8d8484
X-ClickHouse-Format: TabSeparated
X-ClickHouse-Timezone: UTC
Keep-Alive: timeout=3, max=999952297d2 to
43cfc72
Compare
| The version is read from the connection — over the native protocol it comes | ||
| from the handshake, and over the HTTP interface it is obtained with a single | ||
| `SELECT version()` and cached for the life of the connection. |
There was a problem hiding this comment.
Fuck the passive voice.
| The version is read from the connection — over the native protocol it comes | |
| from the handshake, and over the HTTP interface it is obtained with a single | |
| `SELECT version()` and cached for the life of the connection. | |
| Reads the version from the native protocol connection handshake or from a | |
| single `SELECT version()` http query and cached for the life of the | |
| connection. |
| /* | ||
| * Report the ClickHouse server version (major.minor.patch) for a binary | ||
| * connection. The native protocol reports the server version during the | ||
| * handshake, so this reads the cached handshake info rather than issuing a |
There was a problem hiding this comment.
| * handshake, so this reads the cached handshake info rather than issuing a | |
| * handshake, so read the cached handshake info rather than issuing a |
| * to all out-params when the version cannot be determined. The result is cached | ||
| * on the connection, so only the first call issues a query. |
There was a problem hiding this comment.
| * to all out-params when the version cannot be determined. The result is cached | |
| * on the connection, so only the first call issues a query. | |
| * to all out-params when the version cannot be determined. Caches the result | |
| * on the connection, so only the first call issues a query. |
|
|
||
| ### ⚡ Improvements | ||
|
|
||
| * Added a `clickhouse_server_version(server)` function reporting the |
There was a problem hiding this comment.
| * Added a `clickhouse_server_version(server)` function reporting the | |
| * Added the `clickhouse_server_version(server)` function, which reports the |
JoshDreamland
left a comment
There was a problem hiding this comment.
Re:caching: this info lives on the connection itself (conn->version), yes, but specifically in the long-lived "gate" connection that all our scans use. So it's only re-fetched when a connection is re-made, which is the right behavior anyway or we could be connecting to a different version without knowing. You don't have to worry about it querying the version for each scan, though.
| /* | ||
| * Build the query directly rather than via new_query(): this file does | ||
| * not include fdw.h (which declares chfdw_get_session_settings), and the | ||
| * version probe needs no session settings. | ||
| */ |
43cfc72 to
915a6fb
Compare
|
Comments updated; active voice, present indicative. |
Expose the ClickHouse server version at any time, including during query
planning, via chfdw_get_server_version(UserMapping*), with a
chfdw_version_ge() comparison helper. This is the reusable plumbing that
lets a later change gate subquery pushdown on the server version so that
older ClickHouse releases fall back gracefully instead of erroring.
- New server_version method on the libclickhouse_methods vtable.
- Binary driver reads the version captured during the native-protocol
handshake (chc_client_server_info).
- HTTP driver fetches it lazily via SELECT version() and caches it on
the connection.
- New clickhouse_server_version(text) SQL function returning
"major.minor.patch" exercises both drivers, covered by the new
server_version regression test.
No behavior change to existing flows: nothing calls the getter at plan
time yet, so planning still opens no connection.
915a6fb to
542e277
Compare
Exposes the ClickHouse server version to the planner via
chfdw_get_server_version(UserMapping*), with achfdw_version_ge()comparison helper. This is the reusable plumbing a follow-up will use to gate
subquery pushdown on the server version, so older ClickHouse releases degrade
gracefully instead of erroring on SQL their analyzer cannot handle.
What's here
server_versionmethod on thelibclickhouse_methodsvtable, backed by asmall dependency-free
ch_server_versionstruct (shared between thePostgres-free driver internals and the FDW layer).
handshake (
chc_client_server_info) — free once the connection exists.and the "connection" is just a curl handle with no server round-trip), so it
fetches
SELECT version()once and caches it on the connection.clickhouse_server_version(text)SQL function returningmajor.minor.patch, which exercises both drivers and is covered by the newserver_versionregression test.Notes
yet, so planning still opens no connection. The (amortized, once-per-session)
plan-time connect arrives with the gate in the follow-up PR.
🤖 Generated with Claude Code