Skip to content

NullPointerException when inserting Cap'N'Proto encoded data with ClickHouseClient #1475

Closed
@ladislavmacoun

Description

@ladislavmacoun

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

  1. Execute a write request with Cap'N'Proto data or any other binary codec other than RowBinary.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions