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

How to insert Array(String) using clickhouse-http-client 4.6 (RowBinary) ?

Open den-crane opened this issue 2 years ago • 2 comments

I checked several closed issues, but it seems something changed, they don't work for me.

I don't see how to write arrays.

ClickHouseRowBinaryProcessor has several serializers like MapSerializer, TupleSerializer, but no ArraySerializer.

den-crane avatar Aug 23 '23 23:08 den-crane

Hi @den-crane, you can use ClickHouseDataProcessor to find proper serializers for serialization, and use *Value object to set values. It's kind of tedius but here below is an example:

// table: (a String, b Nullable(String), c Array(String))
try (ClickHousePipedOutputStream stream = ClickHouseDataStreamFactory.getInstance()
        .createPipedOutputStream(config, (Runnable) null)) {
    // in async mode, which is default, execution happens in a worker thread
    future = request.data(stream.getInputStream()).execute();

    List<ClickHouseColumn> columns = ClickHouseColumn
            .parse("a String, b Nullable(String), c Array(String)");
    ClickHouseDataProcessor processor = ClickHouseDataStreamFactory.getInstance().getProcessor(config, null,
            stream, null, columns);
    ClickHouseValue[] values = new ClickHouseValue[] {
            ClickHouseStringValue.ofNull(), // columns.get(0).newValue()
            ClickHouseStringValue.ofNull(), // columns.get(1).newValue()
            ClickHouseArrayValue.of(new String[0]) // columns.get(2).newValue()
    };
    ClickHouseSerializer[] serializers = processor.getSerializers(config, columns);
    // writing happens in main thread
    for (int i = 0; i < 10_000; i++) {
        serializers[0].serialize(values[0].update(String.valueOf(i % 16)), stream);
        serializers[1].serialize(values[1].update(UUID.randomUUID().toString()), stream);
        serializers[2].serialize(values[2].update(new String[] { "1", "2" }), stream);
    }
}

// response should be always closed
try (ClickHouseResponse response = future.get()) {
    ClickHouseResponseSummary summary = response.getSummary();
    return summary.getWrittenRows();
}

zhicwu avatar Aug 24 '23 10:08 zhicwu