Skip to content
Open
Changes from all 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
131 changes: 85 additions & 46 deletions integrations/language-clients/java/jdbc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -197,25 +197,25 @@ There are few ways to change the mapping:

| ClickHouse Type | JDBC Type | Java Class |
|-----------------------------|------------------------------|-----------------------------|
| Int8 | TINYINT | java.lang.Byte |
| Int16 | SMALLINT | java.lang.Short |
| Int32 | INTEGER | java.lang.Integer |
| Int64 | BIGINT | java.lang.Long |
| Int128 | OTHER | java.math.BigInteger |
| Int256 | OTHER | java.math.BigInteger |
| UInt8 | OTHER | java.lang.Short |
| UInt16 | OTHER | java.lang.Integer |
| UInt32 | OTHER | java.lang.Long |
| UInt64 | OTHER | java.math.BigInteger |
| UInt128 | OTHER | java.math.BigInteger |
| UInt256 | OTHER | java.math.BigInteger |
| Float32 | REAL | java.lang.Float |
| Float64 | DOUBLE | java.lang.Double |
| Decimal32 | DECIMAL | java.math.BigDecimal |
| Decimal64 | DECIMAL | java.math.BigDecimal |
| Decimal128 | DECIMAL | java.math.BigDecimal |
| Decimal256 | DECIMAL | java.math.BigDecimal |
| Bool | BOOLEAN | java.lang.Boolean |
| Int8 | TINYINT (-6) | java.lang.Byte |
| Int16 | SMALLINT (5) | java.lang.Short |
| Int32 | INTEGER (4) | java.lang.Integer |
| Int64 | BIGINT (-5) | java.lang.Long |
| Int128 | NUMERIC (2) | java.math.BigInteger |
| Int256 | NUMERIC (2) | java.math.BigInteger |
| UInt8 | SMALLINT (5) | java.lang.Short |
| UInt16 | INTEGER (4) | java.lang.Integer |
| UInt32 | BIGINT (-5) | java.lang.Long |
| UInt64 | NUMERIC (2) | java.math.BigInteger |
| UInt128 | NUMERIC (2) | java.math.BigInteger |
| UInt256 | NUMERIC (2) | java.math.BigInteger |
| Float32 | FLOAT (6) | java.lang.Float |
| Float64 | DOUBLE (8) | java.lang.Double |
| Decimal32 | DECIMAL (3) | java.math.BigDecimal |
| Decimal64 | DECIMAL (3) | java.math.BigDecimal |
| Decimal128 | DECIMAL (3) | java.math.BigDecimal |
| Decimal256 | DECIMAL (3) | java.math.BigDecimal |
| Bool | BOOLEAN (16) | java.lang.Boolean |

- numeric types are interconvertible. So `Int8` can be get as `Float64` and vice versa.:
- `rs.getObject(1, Float64.class)` will return `Float64` value of `Int8` column.
Expand All @@ -230,8 +230,8 @@ There are few ways to change the mapping:

| ClickHouse Type | JDBC Type | Java Class |
|-----------------------------|------------------------------|-----------------------------|
| String | VARCHAR | java.lang.String |
| FixedString | VARCHAR | java.lang.String |
| String | VARCHAR (12) | java.lang.String |
| FixedString | VARCHAR (12) | java.lang.String |

- `String` can be read only as `java.lang.String` or `byte[]`.
- `FixedString` is read as is and will be padded with zeros to the length of the column. (For example `FixedString(10)` for `'John'` will be read as `'John\0\0\0\0\0\0\0\0\0'`.)
Expand All @@ -240,8 +240,8 @@ There are few ways to change the mapping:

| ClickHouse Type | JDBC Type | Java Class |
|-----------------------------|------------------------------|-----------------------------|
| Enum8 | OTHER | java.lang.String |
| Enum16 | OTHER | java.lang.String |
| Enum8 | VARCHAR (12) | java.lang.String |
| Enum16 | VARCHAR (12) | java.lang.String |

- `Enum8` and `Enum16` are mapped to `java.lang.String` by default.
- Enum values can be read as numeric values using designtated getter method or `getObject(columnIndex, Integer.class)` method.
Expand All @@ -252,12 +252,12 @@ There are few ways to change the mapping:

| ClickHouse Type | JDBC Type | Java Class |
|-----------------------------|------------------------------|-----------------------------|
| Date | DATE | java.sql.Date |
| Date32 | DATE | java.sql.Date |
| DateTime | TIMESTAMP | java.sql.Timestamp |
| DateTime64 | TIMESTAMP | java.sql.Timestamp |
| Time | TIME | java.sql.Time |
| Time64 | TIME | java.sql.Time |
| Date | DATE (91) | java.sql.Date |
| Date32 | DATE (91) | java.sql.Date |
| DateTime | TIMESTAMP (93) | java.sql.Timestamp |
| DateTime64 | TIMESTAMP (93) | java.sql.Timestamp |
| Time | TIME (92) | java.sql.Time |
| Time64 | TIME (92) | java.sql.Time |

- Date / Time types are mapped to `java.sql` types for better compatibility with JDBC. However getting `java.time.LocalDate`, `java.time.LocalDateTime`, `java.time.LocalTime` is possible by using `ResultSet#getObject(columnIndex, Class<T>)` with the corresponding class as the second argument.
- `rs.getObject(1, java.time.LocalDate.class)` will return `java.time.LocalDate` value of `Date` column.
Expand All @@ -269,12 +269,12 @@ There are few ways to change the mapping:

**Nested Types**

| ClickHouse Type | JDBC Type | Java Class |
|-----------------------------|------------------------------|-----------------------------|
| Array | ARRAY | java.sql.Array |
| Tuple | OTHER | com.clickhouse.data.Tuple |
| Map | JAVA_OBJECT | java.util.Map |
| Nested | ARRAY | java.sql.Array |
| ClickHouse Type | JDBC Type | Java Class |
|-----------------------------|------------------------------|-------------------------------------|
| Array | ARRAY (2003) | java.sql.Array |
| Tuple | OTHER (1111) | com.clickhouse.data.Tuple |
| Map | JAVA_OBJECT (2000) | java.util.Map |
| Nested | ARRAY (2003) | java.sql.Array |

- `Array` is mapped to `java.sql.Array` by default to be compatible with JDBC. This is also done to give more information about returned array value. Useful for type inference.
- `Array` implements `getResultSet()` method to return `java.sql.ResultSet` with the same content as the original array.
Expand All @@ -284,6 +284,45 @@ There are few ways to change the mapping:
- `Tuple` is mapped to `Object[]` because it can contain different types and using `List` isn't valid.
- `Tuple` can be read as `Array` by using `getObject(columnIndex, Array.class)` method. In this case `Array#baseTypeName` will return `Tuple` column definition.

**Array Element Type Metadata**

`Array.getBaseTypeName()` returns the ClickHouse element type name; `Array.getBaseType()` returns the JDBC type code.
JDBC V2 preserves full type signatures (wrapper types, type parameters) that V1 strips.

**JDBC V2**

| ClickHouse Type (Example) | `getBaseTypeName()` | `getBaseType()` |
|-----------------------------------------------------|----------------------------------------------|------------------|
| Array(Int8) | Int8 | TINYINT (-6) |
| Array(Int16) | Int16 | SMALLINT (5) |
| Array(Int32) | Int32 | INTEGER (4) |
| Array(Int64) | Int64 | BIGINT (-5) |
| Array(UInt8) | UInt8 | SMALLINT (5) |
| Array(UInt16) | UInt16 | INTEGER (4) |
| Array(UInt32) | UInt32 | BIGINT (-5) |
| Array(UInt64) | UInt64 | NUMERIC (2) |
| Array(Float32) | Float32 | FLOAT (6) |
| Array(Float64) | Float64 | DOUBLE (8) |
| Array(String) | String | VARCHAR (12) |
| Array(FixedString(8)) | FixedString(8) | VARCHAR (12) |
| Array(Bool) | Bool | BOOLEAN (16) |
| Array(Date) | Date | DATE (91) |
| Array(DateTime) | DateTime | TIMESTAMP (93) |
| Array(UUID) | UUID | OTHER (1111) |
| Array(Nullable(Int32)) | Nullable(Int32) | INTEGER (4) |
| Array(Nullable(String)) | Nullable(String) | VARCHAR (12) |
| Array(LowCardinality(String)) | LowCardinality(String) | VARCHAR (12) |
| Array(LowCardinality(Nullable(String))) | LowCardinality(Nullable(String)) | VARCHAR (12) |
| Array(Array(Int32)) | Int32 | INTEGER (4) |
| Array(Array(Array(String))) | String | VARCHAR (12) |
| Array(Tuple(name String, val Int32)) | Tuple(name String, val Int32) | OTHER (1111) |
| Array(Enum8('alpha' = 1, 'beta' = 2, 'gamma' = 3)) | Enum8('alpha' = 1, 'beta' = 2, 'gamma' = 3) | VARCHAR (12) |

- In V2, `getBaseTypeName()` preserves the full type signature including wrapper types (`Nullable`, `LowCardinality`) and type parameters (`FixedString(8)`, full `Enum` and `Tuple` definitions). V1 strips these and returns only the base type name.
- `Tuple` arrays use `OTHER (1111)` in V2 instead of `STRUCT (2002)` because ClickHouse tuples have named fields, which `java.sql.Struct` does not support.
- `UUID` arrays use `OTHER (1111)` in V2, matching the scalar `UUID` mapping.
- `Enum` values map to `VARCHAR` — enum members are identified by string name regardless of their underlying numeric encoding.

**Writing Arrays**

Use `java.sql.Connection#createArrayOf` to instantiate `java.sql.Array` object. This object is designed to make array handling unified across different databases.
Expand Down Expand Up @@ -688,15 +727,15 @@ try (Connection conn = DriverManager.getConnection(url, properties)) {
| Int16 | ✅ | SMALLINT | java.lang.Short | SMALLINT | java.lang.Short |
| Int32 | ✅ | INTEGER | java.lang.Integer | INTEGER | java.lang.Integer |
| Int64 | ✅ | BIGINT | java.lang.Long | BIGINT | java.lang.Long |
| Int128 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| Int256 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| UInt8 | ❌ | OTHER | java.lang.Short | OTHER | com.clickhouse.data.value.UnsignedByte |
| UInt16 | ❌ | OTHER | java.lang.Integer | OTHER | com.clickhouse.data.value.UnsignedShort |
| UInt32 | ❌ | OTHER | java.lang.Long | OTHER | com.clickhouse.data.value.UnsignedInteger |
| UInt64 | ❌ | OTHER | java.math.BigInteger | OTHER | com.clickhouse.data.value.UnsignedLong |
| UInt128 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| UInt256 | ✅ | OTHER | java.math.BigInteger | OTHER | java.math.BigInteger |
| Float32 | ✅ | REAL | java.lang.Float | REAL | java.lang.Float |
| Int128 | ✅ | NUMERIC | java.math.BigInteger | NUMERIC | java.math.BigInteger |
| Int256 | ✅ | NUMERIC | java.math.BigInteger | NUMERIC | java.math.BigInteger |
| UInt8 | ❌ | SMALLINT | java.lang.Short | SMALLINT | com.clickhouse.data.value.UnsignedByte |
| UInt16 | ❌ | INTEGER | java.lang.Integer | INTEGER | com.clickhouse.data.value.UnsignedShort |
| UInt32 | ❌ | BIGINT | java.lang.Long | BIGINT | com.clickhouse.data.value.UnsignedInteger |
| UInt64 | ❌ | NUMERIC | java.math.BigInteger | NUMERIC | com.clickhouse.data.value.UnsignedLong |
| UInt128 | ✅ | NUMERIC | java.math.BigInteger | NUMERIC | java.math.BigInteger |
| UInt256 | ✅ | NUMERIC | java.math.BigInteger | NUMERIC | java.math.BigInteger |
| Float32 | ✅ | FLOAT | java.lang.Float | FLOAT | java.lang.Float |
| Float64 | ✅ | DOUBLE | java.lang.Double | DOUBLE | java.lang.Double |
| Decimal32 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
| Decimal64 | ✅ | DECIMAL | java.math.BigDecimal | DECIMAL | java.math.BigDecimal |
Expand All @@ -723,8 +762,8 @@ try (Connection conn = DriverManager.getConnection(url, properties)) {
|-----------------------------|-------------------|----------------------------|----------------------------|----------------------------|-----------------------------------------|
| Date | ❌ | DATE | java.sql.Date | DATE | java.time.LocalDate |
| Date32 | ❌ | DATE | java.sql.Date | DATE | java.time.LocalDate |
| DateTime | ❌ | TIMESTAMP | java.sql.Timestamp | TIMESTAMP | java.time.OffsetDateTime |
| DateTime64 | ❌ | TIMESTAMP | java.sql.Timestamp | TIMESTAMP | java.time.OffsetDateTime |
| DateTime | ❌ | TIMESTAMP | java.sql.Timestamp | TIMESTAMP_WITH_TIMEZONE | java.time.OffsetDateTime |
| DateTime64 | ❌ | TIMESTAMP | java.sql.Timestamp | TIMESTAMP_WITH_TIMEZONE | java.time.OffsetDateTime |
| Time | ✅ | TIME | java.sql.Time | new type/not supported | new type/not supported |
| Time64 | ✅ | TIME | java.sql.Time | new type/not supported | new type/not supported |

Expand Down