Présentation

clickhouse‑c est une bibliothèque C header‑only destinée aux environnements embarqués. Elle décode le Native wire format de ClickHouse, c’est‑à‑dire le protocole binaire transporté sur TCP. Le projet se limite à un seul fichier d’en‑tête principal (clickhouse.h) auquel on peut ajouter des en‑têtes optionnels pour la gestion du réseau, de la compression ou des back‑ends d’I/O. Aucun code spécifique à PostgreSQL n’est inclus, même si la bibliothèque a été conçue pour être intégrée dans des extensions PostgreSQL via les allocateurs palloc et longjmp.

Architecture et utilisation

Le modèle d’inclusion repose sur une macro sentinel : un seul fichier source définit CHC_IMPLEMENTATION et inclut les en‑têtes, tandis que les autres fichiers ne font qu’inclure les déclarations. Cette approche évite les dépendances d’édition de liens et garantit que la bibliothèque reste sans dépendance externe autre que la libc. Un helper d’allocation standard est disponible via #define CHC_PROVIDE_STDLIB_ALLOC, ce qui permet d’utiliser malloc/realloc/free sans configuration supplémentaire.

#define CHC_PROVIDE_STDLIB_ALLOC
#define CHC_IMPLEMENTATION
#include "clickhouse.h"
#include "clickhouse-posix-io.h"
#include <stdio.h>
#include <unistd.h>
int main(void) {
    int fd = /* pipe read end */;
    chc_alloc al = chc_alloc_stdlib();
    chc_posix_io state; chc_io io;
    chc_posix_io_init(&state, &io, fd, NULL, NULL);
    // ... lecture du flux natif ...
}

Le code d’exemple montre comment décoder un flux clickhouse‑local --format Native sans établir de connexion TCP ni appliquer de compression. Le lecteur de bloc (chc_block_read) conserve les octets excédentaires entre deux blocs, ce qui optimise la lecture séquentielle.

Analyse des performances et limites

La bibliothèque supporte la compression LZ4 et ZSTD via les en‑têtes clickhouse-compression.h. Les adaptateurs sont désactivables à la compilation avec les macros CHC_NO_LZ4 et CHC_NO_ZSTD, ce qui réduit la taille du binaire pour les systèmes très contraints. La fonction de hachage CityHash128 est utilisée pour le dispatch des codecs, offrant un compromis entre vitesse et distribution uniforme des clés. Cependant, la lecture du format natif nécessite que le serveur ClickHouse désactive l’encodage des types dans le format binaire (output_format_native_encode_types_in_binary_format = 0). Sans ce réglage, le serveur ajoute des balises de type qui provoquent l’erreur CHC_ERR_TYPE, interrompant le décodage.

En l’absence de connexion TCP, la bibliothèque ne gère pas les mécanismes de reconnexion ou de multiplexage, ce qui la rend inadaptée aux scénarios de haute disponibilité où le client doit basculer entre plusieurs nœuds ClickHouse. De plus, le modèle d’allocation basé sur la libc peut entraîner des fragments de mémoire dans des environnements à faible capacité si les blocs sont très volumineux.

Intégration et extensibilité

Pour les extensions PostgreSQL, le projet pg_clickhouse montre comment remplacer l’allocation standard par les fonctions palloc/repalloc/pfree. La séparation claire entre le client « asynchrone » (clickhouse-async.h) et le client « ioless » (clickhouse-client.h) permet d’utiliser la même logique de décodage dans des contextes réseau ou purement file‑based. Cette modularité facilite l’ajout de nouveaux codecs ou de protocoles de transport sans toucher au cœur du décodage, ce qui est essentiel pour les projets embarqués où chaque octet compte.