You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Custom mapping is part of JDBC responsibility. Client provides rich API to get values in different forms. If more custom conversion is needed it is part of external work and application responsibility.
JDBC is the layer that used for its portability and conversion in its case is main job it does.
The problem mainly relate to CH types that hardly can be mapped to Java conterpart. For example, UInt64 doesn't fit long so it can be returned as BigInteger or as String. By default, JDBC driver
returns BigInteger but user want to get String instead. What is completely valid case. In the JDBC context it means that columns that have UInt64 like types should be presented as if they are String
columns. There are two parts of support: one is what ResultSet#getObject() returns and another is ResultSetMetadata that describes structure of result set. The last one must return String type
for such columns.
Custom mapping implementation is complex because of many different classes involved. It requires extensive testing and some preparation. Here are overall steps needed for implementation.
Today we need to add next conversion to java.lang.String for types: UInt64, UInt128, Int128, UInt256, Int256, Float32, Float64, BFloat16, Decimal, Decimal32, Decimal64, Decimal128, Decimal256.
It means columns with only this base types can be converted to String. No Dynamic, no Variant, no nested types would work that way. This should be clearly documented.
Closes
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
Medium Risk
Touches core result-set type binding and connection configuration; mis-mapped types could cause runtime conversion errors, but behavior is opt-in via driver properties and covered by new integration tests.
Overview
Adds configurable JDBC type mappings so ClickHouse column types (e.g. UInt64) can be read as a chosen Java type such as String, with metadata and getObject() staying aligned.
Configuration: New driver properties jdbc_type_mappings (and deprecated typeMappings) accept comma-separated ClickHouseType=JavaClass pairs via URL or Properties. JdbcConfiguration parses them into an immutable map (with common class name shortcuts and Class.forName fallback); specifying both property names fails at connect time.
Connection API:Connection#getTypeMap / setTypeMap are implemented (replacing unsupported stubs). The connection keeps an immutable type map snapshot; result sets capture it at open so concurrent setTypeMap does not change binding mid-iteration.
Binding logic: Column class/JDBC type resolution moves into ResultSetMetaDataImpl (per-column bindings + resolveColumnClass). ResultSetImpl and prepared-statement metadata pass the connection type map so overrides affect getColumnClassName, getColumnType, and getObject (including pre-execute prepared metadata from query schema). JdbcUtils adds CLASS_TO_SQL_TYPE_MAP so overridden Java classes map back to a sensible JDBC type.
Minor:ClientUtils gains isBlank / refactors isNotBlank. Integration tests cover URL/properties parsing, connection type map, metadata, and result materialization.
Reviewed by Cursor Bugbot for commit 0fdaafa. Bugbot is set up for automated code reviews on this repo. Configure here.
Repository collaborators can run the JMH benchmark suite against this PR by commenting:
/benchmark
Optional regression threshold override (Δ% on Time or Alloc/op; defaults to 10%):
/benchmark threshold=15
Only one benchmark run per PR is active at a time — issuing a new /benchmark comment cancels the previous run. After the run finishes a separate comment will be posted comparing it against the latest scheduled run on main; the PR check fails if any benchmark regresses by more than the threshold.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Custom mapping is part of JDBC responsibility. Client provides rich API to get values in different forms. If more custom conversion is needed it is part of external work and application responsibility.
JDBC is the layer that used for its portability and conversion in its case is main job it does.
The problem mainly relate to CH types that hardly can be mapped to Java conterpart. For example,
UInt64doesn't fitlongso it can be returned asBigIntegeror asString. By default, JDBC driverreturns
BigIntegerbut user want to getStringinstead. What is completely valid case. In the JDBC context it means that columns that haveUInt64like types should be presented as if they areStringcolumns. There are two parts of support: one is what
ResultSet#getObject()returns and another isResultSetMetadatathat describes structure of result set. The last one must returnStringtypefor such columns.
Custom mapping implementation is complex because of many different classes involved. It requires extensive testing and some preparation. Here are overall steps needed for implementation.
Today we need to add next conversion to
java.lang.Stringfor types:UInt64,UInt128,Int128,UInt256,Int256,Float32,Float64,BFloat16,Decimal,Decimal32,Decimal64,Decimal128,Decimal256.It means columns with only this base types can be converted to
String. NoDynamic, noVariant, no nested types would work that way. This should be clearly documented.Closes
Checklist
Delete items not relevant to your PR:
Note
Medium Risk
Touches core result-set type binding and connection configuration; mis-mapped types could cause runtime conversion errors, but behavior is opt-in via driver properties and covered by new integration tests.
Overview
Adds configurable JDBC type mappings so ClickHouse column types (e.g.
UInt64) can be read as a chosen Java type such asString, with metadata andgetObject()staying aligned.Configuration: New driver properties
jdbc_type_mappings(and deprecatedtypeMappings) accept comma-separatedClickHouseType=JavaClasspairs via URL orProperties.JdbcConfigurationparses them into an immutable map (with common class name shortcuts andClass.forNamefallback); specifying both property names fails at connect time.Connection API:
Connection#getTypeMap/setTypeMapare implemented (replacing unsupported stubs). The connection keeps an immutable type map snapshot; result sets capture it at open so concurrentsetTypeMapdoes not change binding mid-iteration.Binding logic: Column class/JDBC type resolution moves into
ResultSetMetaDataImpl(per-column bindings +resolveColumnClass).ResultSetImpland prepared-statement metadata pass the connection type map so overrides affectgetColumnClassName,getColumnType, andgetObject(including pre-execute prepared metadata from query schema).JdbcUtilsaddsCLASS_TO_SQL_TYPE_MAPso overridden Java classes map back to a sensible JDBC type.Minor:
ClientUtilsgainsisBlank/ refactorsisNotBlank. Integration tests cover URL/properties parsing, connection type map, metadata, and result materialization.Reviewed by Cursor Bugbot for commit 0fdaafa. Bugbot is set up for automated code reviews on this repo. Configure here.