Появился clickhouse-c: клиент на C для нативного протокола ClickHouse

Появился clickhouse-c: клиент на C для нативного протокола ClickHouse

clickhouse-c, это header-only клиент на языке C для нативного формата передачи данных ClickHouse: Native Protocol поверх TCP, который несёт блоки в формате Native. Библиотека состоит из одного основного заголовка clickhouse.h и необязательных дополнительных заголовков для TCP, сжатия, кодеков и бэкендов ввода-вывода.

По README, библиотека спроектирована для встраивания в расширения PostgreSQL (арена palloc, longjmp), но PG-специфичного кода в ней нет. Один clickhouse.h уже даёт чистый декодер блоков поверх переданного вызывающим кодом интерфейса chc_io: им можно читать FORMAT Native из clickhouse-local через канал (pipe) без TCP, без сжатия и без зависимостей на этапе компоновки, кроме libc.

В примере demo.c (сборка: cc -std=c11 -O2 -I. demo.c -o demo) определяются макросы CHC_PROVIDE_STDLIB_ALLOC и CHC_IMPLEMENTATION, подключаются clickhouse.h и clickhouse-posix-io.h, затем создаётся читатель chc_in через chc_in_init, а в цикле вызывается chc_block_read. Один постоянный читатель обслуживает весь поток: байты, прочитанные за границей блока, остаются в буфере для следующего блока. Строки и столбцы обходятся через chc_block_n_rows и chc_block_n_columns, блок освобождается chc_block_destroy. Законченная версия лежит в examples/minimal_decode.c.

Обязательная настройка сервера: output_format_native_encode_types_in_binary_format = 0 (в пакете Query для TCP или флагом для clickhouse local). Без неё сервер отдаёт бинарные теги типов, и chc_block_read возвращает CHC_ERR_TYPE.

Распространяется библиотека плоским набором заголовков: каждый содержит и объявления, и реализацию под защитой макроса-стража. Ровно одна единица трансляции у потребителя определяет CHC_IMPLEMENTATION и подключает заголовки; остальные подключают только объявления. Вспомогательные функции malloc/realloc/free из stdlib доступны через CHC_PROVIDE_STDLIB_ALLOC; как подключать palloc/repalloc/pfree в настоящем расширении PostgreSQL, README предлагает посмотреть в pg_clickhouse и pg_stat_ch. Дополнительные заголовки независимы друг от друга, а clickhouse-client.h поддерживает ClickHouse 23.3 и новее. Справка по каждому заголовку лежит в doc/, примеры, в examples/.

Тесты запускаются через ./test.sh, можно указать отдельные тесты по базовым именам. test_client_tcp сам поднимает clickhouse server из PATH; если задать CHC_TEST_PORT, тест пойдёт на уже запущенный сервер, например, на старый релиз в docker (clickhouse/clickhouse-server:23.3.22.3 с пробросом порта 19233). Скрипт tools/capture.py проксирует такой сервер, чтобы записывать фикстуры для воспроизведения вроде test/ch23_3_sparse.bin.

Отдельно README перечисляет, что библиотека делать не собирается: протокол HTTP (предлагается оборачивать libcurl напрямую); DNS, раунд-робин по конечным точкам, пулы соединений, повторы и отсрочки; жизненный цикл контекста SSL/TLS (через обратные вызовы chc_io, OpenSSL ведёт вызывающий код); многопоточность (каждый chc_client однопоточный по замыслу); асинхронный ввод-вывод внутри библиотеки (блокирующий клиент синхронно вызывает chc_io.read, а для клиента без собственного ввода-вывода, управляемого из цикла событий, есть clickhouse-async.h). Наконец, в версии v1 не поддержано декодирование Variant, Dynamic, JSON и AggregateFunction: формат передачи в этих типах в ветках 25.x / 26.x ещё меняется.

Ключевые факты

  • clickhouse-c, header-only клиент на C для нативного формата ClickHouse (Native Protocol поверх TCP, блоки формата Native): один основной заголовок clickhouse.h и необязательные заголовки для TCP, сжатия, кодеков и бэкендов ввода-вывода.
  • Рассчитан на встраивание в расширения PostgreSQL (арена palloc, longjmp), но PG-специфичного кода не содержит; один clickhouse.h уже работает как декодер блоков из канала clickhouse-local без TCP и сжатия, с зависимостью только от libc.
  • Требует настройки сервера output_format_native_encode_types_in_binary_format = 0; иначе chc_block_read возвращает CHC_ERR_TYPE. Заголовок clickhouse-client.h поддерживает ClickHouse 23.3 и новее.
  • Сознательно не включает HTTP, DNS и пулы соединений, повторы, управление SSL/TLS и многопоточность; клиент однопоточный.
  • В v1 не поддержано декодирование Variant, Dynamic, JSON и AggregateFunction: их формат передачи в ClickHouse 25.x / 26.x ещё меняется.

Почему это важно

Для программ на C, а также для расширений PostgreSQL, которым нужно читать данные из ClickHouse, это компактный способ говорить с сервером на родном бинарном протоколе без тяжёлых зависимостей: ядро, один заголовок и libc, а остальное подключается по необходимости. Новость нишевая и к нейросетям прямого отношения не имеет: это инженерный инструмент для работы с базой данных.

Кому это важно

Авторам расширений PostgreSQL и другого системного кода на C, которым нужен клиент ClickHouse с управляемой памятью (набор функций palloc/repalloc/pfree) и без навязанного ввода-вывода. Также тем, кто хочет декодировать вывод clickhouse-local в формате Native из канала без TCP и сжатия. Тем, кому нужны пулы соединений, HTTP или многопоточность, библиотека эти задачи оставляет вызывающему коду.

Как это применить

Подключите clickhouse.h и нужные дополнительные заголовки (например, clickhouse-posix-io.h, clickhouse-client.h, clickhouse-compression.h). В одной единице трансляции определите CHC_IMPLEMENTATION перед подключением, в остальных включайте только объявления. Для быстрого старта можно определить CHC_PROVIDE_STDLIB_ALLOC и взять аллокатор на malloc/realloc/free; в расширении PostgreSQL подключайте palloc по образцу pg_clickhouse или pg_stat_ch. Не забудьте выставить output_format_native_encode_types_in_binary_format = 0. Проверить сборку можно через ./test.sh, а полный пример чтения, examples/minimal_decode.c. Цена и лицензия в тексте README не указаны.

Можно ли доверять

Пересказ основан только на тексте README из репозитория. В нём не указаны номер версии и дата релиза, лицензия, авторы или организация, нет бенчмарков и данных о том, кто использует библиотеку в продакшене. Не сказано и то, что сама компания ClickHouse официально поддерживает эту библиотеку. Статус готовности к промышленной эксплуатации прямо не заявлен, кроме ограничений v1 для типов Variant, Dynamic, JSON и AggregateFunction.

Риски и подводные камни

Без настройки output_format_native_encode_types_in_binary_format = 0 чтение блоков завершится ошибкой CHC_ERR_TYPE. В v1 нельзя декодировать Variant, Dynamic, JSON и AggregateFunction, а формат передачи этих типов в ветках 25.x / 26.x ещё меняется. Клиент однопоточный и не включает пулы соединений, повторы, DNS и HTTP, поэтому всё это придётся делать самостоятельно. Блокирующий клиент синхронно вызывает chc_io.read; для событийного цикла нужен отдельный clickhouse-async.h. Поддержка серверов заявлена начиная с ClickHouse 23.3.