clickhouse-java icon indicating copy to clipboard operation
clickhouse-java copied to clipboard

jdbc-v2: Issue with parameter data type

Open jnd77 opened this issue 4 weeks ago • 1 comments

Description

When running a prepared statement with COALESCE and a date, the execution fails due to type.

Am not entirely sure whether it's an issue with the JDBC driver (which serializes the date as a String in PreparedStatementImpl#encodeObject - nothing wrong with that) or the server (which should deserialize it with the proper type, or COALESCE which should handle types better - see https://github.com/ClickHouse/ClickHouse/issues/57292 , although most other databases handle this use case).

Steps to reproduce

See the code below.

Error Log or Exception StackTrace

Caused by: com.clickhouse.client.api.ServerException: Code: 386. DB::Exception: There is no supertype for types Date32, String because some of them are String/FixedString/Enum and some of them are not: In scope SELECT COALESCE(date, '2025-12-31') FROM test_local_date. (NO_COMMON_TYPE) (version 25.8.7.3 (official build)) 
	at com.clickhouse.client.api.internal.HttpAPIClientHelper.readError(HttpAPIClientHelper.java:403)

Expected Behaviour

The query should return without error.

Code Example

  @Test
  void required_testJdbcWithLocalDate() throws Exception {
    final String url = "jdbc:ch://localhost:" + SERVER.getFirstMappedPort();

    final Properties info = new Properties();
    info.put("user", SERVER.getClickhouseUser());
    info.put("password", SERVER.getClickhousePassword());

    try (final Connection conn = DriverManager.getConnection(url, info)) {
      conn.prepareStatement("CREATE TABLE test_local_date"
          + " (id Int64, date Nullable(Date32)) ENGINE = MergeTree() ORDER BY id").execute();
      conn.prepareStatement("INSERT INTO test_local_date VALUES (1, null)").execute();
      try (final PreparedStatement preparedStatement = conn.prepareStatement("SELECT COALESCE(date, ?) FROM test_local_date")) {
        preparedStatement.setObject(1, LocalDate.of(2025, 12, 31));
        preparedStatement.executeQuery();
      }
    }
  }

Configuration

Client Configuration

Environment

  • [ ] Cloud
  • Client version: clickhouse-jdbc 0.9.4
  • Language version:
  • OS:

ClickHouse Server

  • ClickHouse Server version: 25.8.7.3

jnd77 avatar Dec 02 '25 02:12 jnd77

Good day, @jnd77 !

Thank you for reporting!

This is the problem in how to represent values like DateTime in text format so it is suitable for functions expecting string and for functions that expect certain type. You may use com.clickhouse.jdbc.PreparedStatementImpl#setObject(int, java.lang.Object, java.sql.SQLType) so driver will add CAST. I agree it is counter-intuitive to pass Date object and get string on server side. There is more simple example SELECT ? where it will become string and we might fail to return Date . We are working on this .

chernser avatar Dec 03 '25 06:12 chernser