ChDriver.Types.Registry (ch_driver v0.3.0)

Copy Markdown

The scalar/fixed-width column type codec table, plus the primitive wire readers it's built on.

Covers ClickHouse's fixed-width integer and float types, String, Bool, DateTime, Enum8/Enum16, UUID, IPv4, and IPv6. Adding a new scalar type is a one-line addition to column_codec/1.

UUID values decode to their standard hyphenated text form. IPv4/IPv6 decode to dotted-quad / colon-hex text. DateTime decodes to a UTC DateTime.t(). Date decodes to a Date.t(). Bool decodes to a boolean.

DateTime64(P) is parameterized by its precision, so it can't be a fixed entry in column_codec/1's table -- it's dispatched from ChDriver.Protocol.NativeBlock through decode_datetime64/2 instead.

Summary

Functions

Looks up the fixed-width/string codec for a scalar ClickHouse type name. Returns {:fixed, byte_size, unpack_fun}, :string, or :unsupported.

Decodes a DateTime64(P) tick count of precision decimal places into a UTC DateTime.t().

Reads num_rows fixed-width byte_size-byte chunks from binary, running each through unpack (e.g. fn <<v::unsigned-little-32>> -> v end). Returns {:ok, values, rest} or {:incomplete, binary} if fewer than num_rows * byte_size bytes are available.

Reads remaining ClickHouse String values (varint length prefix + bytes) from binary. Returns {:ok, values, rest} or {:incomplete, binary}.

Functions

column_codec(arg1)

Looks up the fixed-width/string codec for a scalar ClickHouse type name. Returns {:fixed, byte_size, unpack_fun}, :string, or :unsupported.

decode_datetime64(arg, precision)

Decodes a DateTime64(P) tick count of precision decimal places into a UTC DateTime.t().

Unlike plain DateTime's unsigned whole-second UInt32, DateTime64 is a signed little-endian Int64 count of 10^-P-second ticks since the Unix epoch, so it covers pre-epoch instants (negative ticks) as well as sub-second resolution.

Elixir's DateTime only carries microsecond resolution, so a precision above 6 (e.g. DateTime64(9)'s nanoseconds) is truncated -- toward negative infinity via Integer.floor_div/2, so that a pre-epoch value's microsecond remainder stays non-negative and the reconstructed DateTime is still the correct instant rather than one second off. The reported microsecond precision is capped at 6 for the same reason, while a lower precision is preserved as-is (a DateTime64(3) value loads back as {ms * 1000, 3}, not silently widened to 6).

decode_fixed_width(binary, num_rows, byte_size, unpack)

Reads num_rows fixed-width byte_size-byte chunks from binary, running each through unpack (e.g. fn <<v::unsigned-little-32>> -> v end). Returns {:ok, values, rest} or {:incomplete, binary} if fewer than num_rows * byte_size bytes are available.

decode_strings(binary, remaining, acc)

Reads remaining ClickHouse String values (varint length prefix + bytes) from binary. Returns {:ok, values, rest} or {:incomplete, binary}.