Changelog
View SourceAll notable changes to this project are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.4.0 - 2026-06-06
Added
- Telemetry instrumentation.
query/2,insert/3, andinsert_stream/3now emit[:huginn, :query, :start | :stop | :exception]span events with metadata (:method,:sql,:query_id,:pool, and:rows/:statson stop). SeeHuginn.Clickhouse.Telemetry. - Built-in default logger.
Huginn.attach_default_logger/1/detach_default_logger/0attach a ready-madeLoggerhandler for the telemetry events. Off by default. - Opt-in retries.
query/2andinsert/3accept:retriesand:retry_backoffoptions to retry transient transport failures (connection errors, gRPCUNAVAILABLE/DEADLINE_EXCEEDED) with exponential backoff. ClickHouse query errors are never retried. SeeHuginn.Clickhouse.Retry. Huginn.Clickhouse.SQL.escape/1for safe single-quoted string literals.Result.parse_output/3, a column-aware variant ofparse_output/2.
Fixed
- Streaming insert (
insert_stream/3) actually works now. It was calling the client-streaming gRPC stub incorrectly (passing the request enumerable as the options argument), so no data was ever sent. It now opens the stream, pushes eachQueryInfowithGRPC.Stub.send_request/3(settingnext_query_infocorrectly and emitting a final END_STREAM frame), and reads the reply withrecv/2. Verified end-to-end against a live ClickHouse. - Bidirectional streaming (
stream_io/1) actually works now. Same underlying stub-call bug, plus the gRPC stream is now driven from a single owner process (gun delivers all stream messages to one process), so sending and consuming replies no longer dead-locks. Verified end-to-end. - CSV parsing now correctly handles quoted fields containing commas,
embedded quotes (
""), and is symmetric with the library's CSV writer. Previously a naive comma split corrupted such rows. JSONEachRowresults now extract values in column order instead of relying on JSON object key order, which could misalign values with columns.- SQL string escaping in
cancel/2now escapes backslashes before quotes, so aquery_idcontaining a trailing backslash can no longer break out of the string literal. stream_io/1now returns{:error, reason}when a channel cannot be acquired instead of raising aMatchErrorin the caller.
Changed
- Upgraded
grpc_connection_poolto~> 0.4.0(from~> 0.2.1). The 0.4.x line is a rewrite with an ETS/atomics zero-GenServer hot path and pluggable selection strategies;Huginn.Clickhouse.Config.to_pool_config/1'sendpoint:/pool:keyword output remains compatible, so no application changes were required. - Public functions now read the application config once per call instead of twice (no behavior change).
cancel_where/2documents that its condition is interpolated verbatim and must come from trusted input only.
Tooling
- Added GitHub Actions CI (
compile --warnings-as-errors,format,credo,test,dialyzer). - Added a tag-triggered release workflow that publishes to Hex on
v*tags (requires aHEX_API_KEYrepository secret). - Added Credo (
.credo.exs) and Dialyzer (dialyxir) to the toolchain. - Added
:telemetryas a direct dependency; bumpedex_docto~> 0.34. - Added an integration test suite (tagged
:integration, excluded by default; run withmix test --include integrationagainst the docker-compose ClickHouse) covering the request/response and streaming paths end-to-end.
0.3.0 - 2025
- Initial public release on Hex: ClickHouse gRPC client supporting all four
ClickHouse gRPC methods (
ExecuteQuery,ExecuteQueryWithStreamInput,ExecuteQueryWithStreamOutput,ExecuteQueryWithStreamIO), connection pooling, password/JWT auth, query cancellation, and result parsing.