ClickHouse / ClickHouse/clickhouse-java

Map(K, V) type support issue

Offen
#3,047 1 Kommentar 2 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug
Vorherrschende Sprache
Java
Sterne
1.6k
Forks
636
Ø Merge
2 T. 23 Std.
Gemergte PRs (30 T.)
29

Beschreibung

## 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(..)](https://github.com/ClickHouse/clickhouse-java/blob/601ade16364d667b71a4982bbabf60ed2d941dc1/client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/BinaryStreamReader.java#L969) 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();
}
}
}
}
```
2. Observe only one value per key returned.
3. 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 getObject(int columnIndex, Class type)` and `Object getObject(int columnIndex, java.util.Map> 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

```sql
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

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne in client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/BinaryStreamReader.java bei readMap(..), und verfolge anschließend die im Issue genannten JDBC ResultSet getObject-Überladungen. Reproduziere die Abfrage mit doppelten Schlüsseln und untersuche, wie Maps auf oberster Ebene, verschachtelte Maps und in Arrays enthaltene Maps gelesen werden. Als erledigt gilt die Aufgabe, wenn das Standardverhalten kompatibel bleibt und die angeforderten Typhinweise doppelte Schlüssel-Wert-Einträge in jedem genannten Szenario erhalten.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
java
Bereich
api, database
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
48/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.