Closed
Description
Describe the bug
When attempting to insert Cap'N'Proto binary encoded data using the edited example, a NullPointerException
is encountered.
The specific error message is:
java.lang.NullPointerException`: Cannot invoke "com.clickhouse.data.ClickHouseDataProcessor.getInputStream()" because "this.processor" is null
Steps to reproduce
- Execute a write request with Cap'N'Proto data or any other binary codec other than RowBinary.
- Attempt to get the response.
Expected behaviour
Using the same code snippet with RowBinary encoded data works as expected, returning the server response.
Code example
public long insert(List<Record> records, ClickHouseNode server) throws ClickHouseException {
if (records.isEmpty()) {
return;
}
try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP)) {
ClickHouseRequest.Mutation request = client
.read(server)
.write()
.table(TABLE_NAME)
.format(ClickHouseFormat.CapnProto)
.set("format_schema", "schema.capnp:Record")
.decompressClientRequest(ClickHouseCompression.LZ4);
ClickHouseConfig config = request.getConfig();
CompletableFuture<ClickHouseResponse> future;
// back-pressuring is not supported, you can adjust the first two arguments
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();
records.stream()
.filter(Objects::nonNull)
.forEach(record -> {
try {
stream.write(record.getPayload());
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
// response should be always closed
try (ClickHouseResponse response = future.get()) {
ClickHouseResponseSummary summary = response.getSummary();
return summary.getWrittenRows();
}
} catch (IOException | InterruptedException | ExecutionException e) {
throw ClickHouseException.of(e, server);
}
}
Configuration
Environment
- Client version: 0.4.6
- Language version: java 21 2023-09-19 LTS
- OS: Linux
It looks like the problem is at the ClickHouseDataStreamFactory
, where any other binary format from RowBinary will return null processor.
public ClickHouseDataProcessor getProcessor(ClickHouseDataConfig config, ClickHouseInputStream input,
ClickHouseOutputStream output, Map<String, Serializable> settings, List<ClickHouseColumn> columns)
throws IOException {
ClickHouseFormat format = ClickHouseChecker.nonNull(config, ClickHouseDataConfig.TYPE_NAME).getFormat();
ClickHouseDataProcessor processor = null;
if (ClickHouseFormat.RowBinary == format || ClickHouseFormat.RowBinaryWithNamesAndTypes == format) {
processor = new ClickHouseRowBinaryProcessor(config, input, output, columns, settings);
} else if (format.isText()) {
processor = new ClickHouseTabSeparatedProcessor(config, input, output, columns, settings);
}
return processor;
}
I would appriciate any assistance addressing this problem or offer any potential solutions or workarounds, thank you.