Changelog

View Source

All 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, and insert_stream/3 now emit [:huginn, :query, :start | :stop | :exception] span events with metadata (:method, :sql, :query_id, :pool, and :rows/:stats on stop). See Huginn.Clickhouse.Telemetry.
  • Built-in default logger. Huginn.attach_default_logger/1 / detach_default_logger/0 attach a ready-made Logger handler for the telemetry events. Off by default.
  • Opt-in retries. query/2 and insert/3 accept :retries and :retry_backoff options to retry transient transport failures (connection errors, gRPC UNAVAILABLE/DEADLINE_EXCEEDED) with exponential backoff. ClickHouse query errors are never retried. See Huginn.Clickhouse.Retry.
  • Huginn.Clickhouse.SQL.escape/1 for safe single-quoted string literals.
  • Result.parse_output/3, a column-aware variant of parse_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 each QueryInfo with GRPC.Stub.send_request/3 (setting next_query_info correctly and emitting a final END_STREAM frame), and reads the reply with recv/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.
  • JSONEachRow results 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/2 now escapes backslashes before quotes, so a query_id containing a trailing backslash can no longer break out of the string literal.
  • stream_io/1 now returns {:error, reason} when a channel cannot be acquired instead of raising a MatchError in the caller.

Changed

  • Upgraded grpc_connection_pool to ~> 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's endpoint:/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/2 documents 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 a HEX_API_KEY repository secret).
  • Added Credo (.credo.exs) and Dialyzer (dialyxir) to the toolchain.
  • Added :telemetry as a direct dependency; bumped ex_doc to ~> 0.34.
  • Added an integration test suite (tagged :integration, excluded by default; run with mix test --include integration against 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.