[v0.10.0-rc1] Binary String Support #2911
Conversation
…rted to StringValue
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
extend AGENTS.md based on CONTIBUTING.md
|
Repository collaborators can run the JMH benchmark suite against this PR by commenting: Optional regression threshold override (Δ% on Time or Alloc/op; defaults to 10%): Only one benchmark run per PR is active at a time — issuing a new |
TriageCategory: Summary What this impacts
Concerns
Required reviewer action
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ 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 cbd500f. Configure here.
| featureManager.unsupportedFeatureThrow("getBinaryStream"); | ||
|
|
||
| return null; | ||
| return getBinaryStream(getSchema().nameToColumnIndex(columnLabel)); |
There was a problem hiding this comment.
JDBC Object getObject returns StringValue
Medium Severity
With binary_string_support enabled, getObject returns internal StringValue for String/FixedString columns without proper conversion. This causes issues when callers expect String (for Object.class) or byte[] (for byte[].class), as JdbcUtils.convert lacks StringValue handling. getString, getBytes, and getBinaryStream are unaffected.
Reviewed by Cursor Bugbot for commit cbd500f. Configure here.
| private Object readNestedValue(ClickHouseColumn column) throws IOException { | ||
| return readValue(column, null, false); | ||
| } | ||
|
|
There was a problem hiding this comment.
skipValue still loads string blobs
Medium Severity
skipValue still calls full readValue for every column. With binary_string_support enabled, skipped top-level String/FixedString columns still allocate a StringValue and backing bytes, so readToPOJO with unmapped large string fields can OOM despite the feature’s lazy-read goal.
Reviewed by Cursor Bugbot for commit cbd500f. Configure here.
📊 ClickHouse client benchmark resultscommit 📊 Benchmark tables ·
|
| query_label | base cold | PR cold | base warm | PR warm | Δ warm | base σ | PR σ |
|---|---|---|---|---|---|---|---|
| SelectHitsCount (compression=on) | 383 | 387 | 9.2 | 6.2 | -32.4% | 2.1 | 0.5 |
| SelectHits (compression=on) | 4536 | 4577 | 3460 | 3350 | -3.2% | 40.1 | 48.1 |
| InsertHits (compression=on) | 1040 | 1080 | 890 | 898 | +0.8% | 11.4 | 37.2 |
| SelectHitsCount (compression=on) | 201 | 193 | 5.5 | 4.8 | -13.6% | 0.6 | 1.0 |
| SelectHits (compression=on) | 4867 | 4883 | 3900 | 3869 | -0.8% | 28.9 | 29.2 |
| InsertHits (compression=on) | 1072 | 1089 | 887 | 878 | -1.0% | 44.8 | 34.0 |
| SelectHitsCount (compression=on) | 454 | 438 | 41.2 | 42.2 | +2.4% | 2.6 | 2.5 |
| SelectHits (compression=on) | 3234 | 3362 | 2102 | 2282 | +8.6% | 61.9 | 36.9 |
| InsertHits (compression=on) | 1926 | 1959 | 1671 | 1824 | +9.2% | 153 | 149 |
| SelectHitsCount (compression=on) | 419 | 422 | 18.0 | 18.8 | +4.2% | 2.7 | 1.7 |
| SelectHits (compression=on) | 5398 | 4646 | 3521 | 3466 | -1.6% | 105 | 91.2 |
| InsertHits (compression=on) | 3310 | 3327 | 2864 | 2722 | -5.0% | 219 | 256 |
Resource usage (lower = better) (per-iteration averages)
peak_memory_mb
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 116 | 116 | +0.3% |
| clickhouse-java-v1 | SelectHits (compression=on) | 1245 | 1238 | -0.5% |
| clickhouse-java-v1 | InsertHits (compression=on) | 1852 | 1857 | +0.3% |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 118 | 117 | -0.7% |
| clickhouse-java-v2 | SelectHits (compression=on) | 1234 | 1236 | +0.2% |
| clickhouse-java-v2 | InsertHits (compression=on) | 1851 | 1859 | +0.4% |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 124 | 127 | +1.9% |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 1243 | 1248 | +0.4% |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 5061 | 6273 | +23.9% |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 131 | 131 | +0.1% |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 1253 | 1243 | -0.9% |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 9349 | 6939 | -25.8% |
user_cpu_ms
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 1211 | 1198 | -1.1% |
| clickhouse-java-v1 | SelectHits (compression=on) | 19148 | 18722 | -2.2% |
| clickhouse-java-v1 | InsertHits (compression=on) | 13292 | 13317 | +0.2% |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 1389 | 1218 | -12.3% |
| clickhouse-java-v2 | SelectHits (compression=on) | 22082 | 21726 | -1.6% |
| clickhouse-java-v2 | InsertHits (compression=on) | 13281 | 13435 | +1.2% |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 1562 | 1616 | +3.5% |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 12993 | 13005 | +0.1% |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 18847 | 19671 | +4.4% |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 1489 | 1393 | -6.4% |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 20105 | 20360 | +1.3% |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 22200 | 21956 | -1.1% |
system_cpu_ms
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 277 | 353 | +27.4% |
| clickhouse-java-v1 | SelectHits (compression=on) | 1792 | 1844 | +2.9% |
| clickhouse-java-v1 | InsertHits (compression=on) | 1035 | 1154 | +11.5% |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 257 | 323 | +25.7% |
| clickhouse-java-v2 | SelectHits (compression=on) | 1041 | 1393 | +33.8% |
| clickhouse-java-v2 | InsertHits (compression=on) | 1164 | 1113 | -4.4% |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 354 | 238 | -32.8% |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 1244 | 1633 | +31.3% |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 2591 | 3749 | +44.7% |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 369 | 519 | +40.7% |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 1382 | 1087 | -21.3% |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 4134 | 3545 | -14.2% |
voluntary_context_switches
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 6500 | 8173 | +25.7% |
| clickhouse-java-v1 | SelectHits (compression=on) | 30359 | 25492 | -16.0% |
| clickhouse-java-v1 | InsertHits (compression=on) | 13647 | 14669 | +7.5% |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 8937 | 8893 | -0.5% |
| clickhouse-java-v2 | SelectHits (compression=on) | 19800 | 21304 | +7.6% |
| clickhouse-java-v2 | InsertHits (compression=on) | 14776 | 15919 | +7.7% |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 9173 | 8584 | -6.4% |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 23357 | 25982 | +11.2% |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 20196 | 20023 | -0.9% |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 9826 | 10231 | +4.1% |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 21863 | 21554 | -1.4% |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 18178 | 17493 | -3.8% |
involuntary_context_switches
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 4 | 20 | +400.0% |
| clickhouse-java-v1 | SelectHits (compression=on) | 82 | 54 | -34.1% |
| clickhouse-java-v1 | InsertHits (compression=on) | 27 | 41 | +51.9% |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 3 | 4 | +33.3% |
| clickhouse-java-v2 | SelectHits (compression=on) | 38 | 43 | +13.2% |
| clickhouse-java-v2 | InsertHits (compression=on) | 39 | 42 | +7.7% |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 4 | 3 | -25.0% |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 28 | 52 | +85.7% |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 42 | 64 | +52.4% |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 1 | 3 | +200.0% |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 87 | 67 | -23.0% |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 60 | 52 | -13.3% |
major_page_faults
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 0 | 0 | — |
| clickhouse-java-v1 | SelectHits (compression=on) | 0 | 0 | — |
| clickhouse-java-v1 | InsertHits (compression=on) | 0 | 0 | — |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 0 | 2 | +∞% |
| clickhouse-java-v2 | SelectHits (compression=on) | 0 | 0 | — |
| clickhouse-java-v2 | InsertHits (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 0 | 0 | — |
minor_page_faults
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 31201 | 31032 | -0.5% |
| clickhouse-java-v1 | SelectHits (compression=on) | 332312 | 319479 | -3.9% |
| clickhouse-java-v1 | InsertHits (compression=on) | 485290 | 483604 | -0.3% |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 31748 | 31056 | -2.2% |
| clickhouse-java-v2 | SelectHits (compression=on) | 320818 | 324021 | +1.0% |
| clickhouse-java-v2 | InsertHits (compression=on) | 487384 | 490027 | +0.5% |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 33320 | 33859 | +1.6% |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 328260 | 330354 | +0.6% |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 1.3M | 1.6M | +23.3% |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 34896 | 35833 | +2.7% |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 330829 | 327068 | -1.1% |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 2.4M | 1.8M | -24.5% |
instructions
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 6.3G | 6.3G | +1.1% |
| clickhouse-java-v1 | SelectHits (compression=on) | 215.5G | 227.9G | +5.7% |
| clickhouse-java-v1 | InsertHits (compression=on) | 98.6G | 99.1G | +0.5% |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 6.6G | 6.3G | -3.4% |
| clickhouse-java-v2 | SelectHits (compression=on) | 271.6G | 273.2G | +0.6% |
| clickhouse-java-v2 | InsertHits (compression=on) | 100.5G | 99.8G | -0.7% |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 7.8G | 7.7G | -0.6% |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 151.1G | 152.8G | +1.1% |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 166.3G | 175.7G | +5.6% |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 7.8G | 8.0G | +2.6% |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 237.5G | 239.9G | +1.0% |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 195.8G | 196.3G | +0.3% |
cpu_cycles
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 3.9G | 4.0G | +2.0% |
| clickhouse-java-v1 | SelectHits (compression=on) | 60.8G | 60.3G | -0.9% |
| clickhouse-java-v1 | InsertHits (compression=on) | 41.7G | 42.0G | +0.8% |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 4.2G | 3.9G | -5.7% |
| clickhouse-java-v2 | SelectHits (compression=on) | 69.3G | 69.1G | -0.3% |
| clickhouse-java-v2 | InsertHits (compression=on) | 42.3G | 42.4G | +0.3% |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 5.0G | 4.9G | -1.9% |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 40.7G | 41.7G | +2.5% |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 59.5G | 64.4G | +8.1% |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 4.8G | 5.0G | +4.3% |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 63.9G | 63.8G | -0.3% |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 71.4G | 70.7G | -1.1% |
cache_misses
| client | query_label | base | PR | Δ |
|---|---|---|---|---|
| clickhouse-java-v1 | SelectHitsCount (compression=on) | 0 | 0 | — |
| clickhouse-java-v1 | SelectHits (compression=on) | 0 | 0 | — |
| clickhouse-java-v1 | InsertHits (compression=on) | 0 | 0 | — |
| clickhouse-java-v2 | SelectHitsCount (compression=on) | 0 | 0 | — |
| clickhouse-java-v2 | SelectHits (compression=on) | 0 | 0 | — |
| clickhouse-java-v2 | InsertHits (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v1 | SelectHitsCount (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v1 | SelectHits (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v1 | InsertHits (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v2 | SelectHitsCount (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v2 | SelectHits (compression=on) | 0 | 0 | — |
| clickhouse-jdbc-v2 | InsertHits (compression=on) | 0 | 0 | — |


Summary
There are a few problems with reading binary strings:
This PR introduces
StringValuethat acts asbyte[]holder to createStringad-hoc instead of when read. So strings that suppose to be read viabyte[]will stay asbyte[].This affects also JDBC where
ResultSethasgetBinaryStreamfor such cases. Now it is supported operation.Part of #2263
Checklist
Delete items not relevant to your PR: