Map(K, V) type support issue

Open
#3,047 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
java
Domain
api, database

Research direction

Start in client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/BinaryStreamReader.java at readMap(..), then trace the JDBC ResultSet getObject overloads named in the issue. Reproduce the duplicate-key query and inspect how top-level, nested, and array-contained maps are read. Done means the default behavior remains compatible while the requested type hints preserve duplicate key-value entries in each stated scenario.

Written by the indexing model from the issue text.

Description

bug

Description

In Clickhouse Map(K, V) is not a collection of unique-by-key pairs, see https://clickhouse.com/docs/sql-reference/data-types/map :

i.e. a map can contain two elements with the same key

But there is no way to obtain any representation other than a Map<,> of unique entries.

All the key-value pairs are being delivered by the underlying protocol, but they are effectively merged while reading an instance of a map in the corresponding readMap(..) method.

The issue affects all scenarios of map usage: top-level value, nested map-in-map, map-in-array, etc.

Steps to reproduce
  1. Execute minimal reproduction program:
public class Program {
	public static void main(String[] args) throws SQLException {
		String queryText = "select map('key', 'X', 'key', 'Y')";
		try (
			Connection cnn = DriverManager.getConnection("jdbc:clickhouse://localhost:11049/default", "default", "");			
			PreparedStatement stmt = cnn.prepareStatement(queryText);
			ResultSet rs = stmt.executeQuery()
		) {
			if (rs.next()) {
				System.out.println(rs.getObject(1)); // gives {key=Y}
			} else {
				throw new IllegalStateException();
			}
		}
	}
}
  1. Observe only one value per key returned.
  2. Any attempt to get other value representations than what getObject() does gives the same or results in an exception being thrown.
Expected Behavior

Supporting existing behavior by default, it is expected to be able to use type hints to affect the actual return value of the getObject(..) method of the java.sql.ResultSet implementation (such overloads as <T> T getObject(int columnIndex, Class<T> type) and Object getObject(int columnIndex, java.util.Map<String,Class<?>> map) specifically, including their counterparts having columnLabel instead of columnIndex):

public class Program {
	public static void main(String[] args) throws SQLException {
		String queryText = "select map('key', 'X', 'key', 'Y')";
		try (
			Connection cnn = DriverManager.getConnection("jdbc:clickhouse://localhost:11049/default", "default", "");			
			PreparedStatement stmt = cnn.prepareStatement(queryText);
			ResultSet rs = stmt.executeQuery()
		) {
			if (rs.next()) {
				System.out.println(rs.getObject(1)); // gives {key=Y} by default

				System.out.println(rs.getObject(1, List.class)); // to give [key=X, key=Y] only for top level
				System.out.println(rs.getObject(1, Map.of("Map", List.class))); // to give [key=X, key=Y] same as above including nested values 
			} else {
				throw new IllegalStateException();
			}
		}
	}
}

Consider changing the default behavior by the time of a certain upcoming major release.

Code Example
select map('key', 'X', 'key', 'Y');

Environment
  • Cloud
  • Client version: 0.10.0-rc2
  • Language version: 21
  • OS: Windows 11
ClickHouse Server
  • ClickHouse Server version: 24.5.3.5
Dominant language
Java
Stars
1.6k
Forks
637
Avg merge
2d 12h
Merged PRs (30d)
28

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ClickHouse/clickhouse-java

All issues in ClickHouse/clickhouse-java

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.