EV-ClickHouse
view release on metacpan or search on metacpan
- 7. Inspect via `dump_state` and `pending_queries`
When a connection seems stuck, `$ch->dump_state` returns a
hashref snapshot (fd state, send/recv buffer pos, callback depth,
pending\_count, ...) and `$ch->pending_queries` lists the
in-flight + queued entries with their query\_ids and age. Both are
read-only debug accessors - safe to call from a signal-handler-style
dump path.
- 8. Don't fight the freelist
The XS layer keeps freelists for both cb\_queue and send\_queue entries,
so allocating callbacks is essentially free after warm-up. The
implication: avoid wrapping the connection in heavy wrappers that
clone the connection per call - there is no per-call setup cost worth
amortising away.
# ARCHITECTURE
The client is a single state machine driven by an [EV](https://metacpan.org/pod/EV) event loop. Each
connection holds: a TCP fd (non-blocking), a send buffer, a receive
buffer, a callback queue (next-in-line per protocol), and a pending
send queue (buffered before connect).
State transitions:
Connect TCP --> [TLS handshake] --> [Native ServerHello]
--> Connected --> { dispatch from send_queue;
parse response; deliver via cb_queue }
The connect\_timeout timer covers all three pre-Connected stages.
auto\_reconnect re-runs the chain via `schedule_reconnect`.
Two key invariants:
- Native protocol is strictly request/response. Only one query is
in-flight per connection at a time. `insert_streamer` serialises
batches against this constraint.
- `callback_depth` guards against `self` being freed mid-callback.
Every callback dispatch increments it; `check_destroyed` defers the
final `Safefree` until depth returns to zero.
For deeper detail (state-machine table, queue semantics) see `CLAUDE.md`
in the source distribution.
# TYPES
Per-column wire format and Perl-side gotchas. All numeric types
round-trip stable raw values by default; opt into string forms via
`decode_datetime`, `decode_decimal`, `decode_enum`.
- Integers
Int8..Int64 / UInt8..UInt64: native Perl IV/UV. Int128/UInt128/Int256/UInt256
return decimal string representations on platforms with `__int128` (Int128/UInt128)
or always for the 256-bit forms.
- Floats
Float32/Float64 round-trip exactly within IEEE-754 limits. `NaN`/`+Inf`/
`-Inf` are preserved.
- BFloat16
Top 16 bits of a Float32. Encoded by truncation; decoded by zero-extension.
Suitable for ML feature columns; not for accounting.
- Decimal32/64/128
Decoded as IV (raw integer) or NV (scaled to N decimal digits if
`decode_decimal => 1`). Decimal128 over very long precision may lose
trailing digits in the NV form; pass `decode_decimal => 0` and divide
yourself with [Math::BigInt](https://metacpan.org/pod/Math%3A%3ABigInt) for exact arithmetic.
- Decimal256
Returns raw 32 LE bytes. Decode with [Math::BigInt](https://metacpan.org/pod/Math%3A%3ABigInt) (see
`eg/decimal_bigmath.pl`).
- Date / Date32 / DateTime / DateTime64
Default: integer (days since epoch / Unix seconds). With `decode_datetime`:
`YYYY-MM-DD` or `YYYY-MM-DD HH:MM:SS` or `YYYY-MM-DD HH:MM:SS.ffffff`.
DateTime carries a timezone string; the formatted output uses it.
- Bool
Decoded as 0/1. Encoded from any truthy/falsy SV. ClickHouse stores
internally as UInt8 0/1.
- String / FixedString
Bytes-in, bytes-out. No UTF-8 transformation.
- UUID
Canonical hex form `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`. Encode
accepts the same.
- IPv4 / IPv6
Dotted-quad / canonical IPv6 strings.
- Enum8 / Enum16
Default: integer code. With `decode_enum => 1`: label string.
- Nullable(T)
`undef` in Perl maps to null; otherwise the inner type's encoding.
- Array(T)
Perl arrayref of inner-type values.
- Tuple(T1, T2, ...)
Perl arrayref ordered as the type declaration. Named tuples
(`Tuple(a Int32, b String)`) are still arrayref-positional;
parse the name from `column_types` if you need it.
( run in 0.840 second using v1.01-cache-2.11-cpan-9581c071862 )