ChDriver.Types (ch_driver v0.3.0)

Copy Markdown

Parses ClickHouse column type strings, e.g. "Nullable(String)" or "Map(String, Decimal(10, 2))", into their component parts.

Pure string parsing — no wire decoding happens here. See ChDriver.Protocol.Block.Wrappers for how the parsed types drive actual column decoding.

Supports Nullable(T), Array(T), Map(K, V), LowCardinality(T), Variant(T1, ..., Tn), Decimal(P, S) (and its Decimal32/64/128/256(S) aliases), DateTime64(P[, 'TZ']), and FixedString(N). Tuple(...) isn't supported as a standalone column type — only as Map's internal representation.

Summary

Functions

Parses ClickHouse's Array(T) wrapper syntax, returning the inner type string.

Parses ClickHouse's DateTime64(P) and DateTime64(P, 'Timezone') types, returning {:ok, precision}.

Parses Decimal(P, S) and the Decimal32(S)/Decimal64(S)/ Decimal128(S)/Decimal256(S) fixed-precision aliases, returning {:ok, precision, scale}.

Parses ClickHouse's FixedString(N) type, returning {:ok, n}.

Parses ClickHouse's LowCardinality(T) wrapper syntax, returning the inner type string.

Parses ClickHouse's Map(K, V) wrapper syntax, returning {:ok, key_type, value_type}. Splits on the top-level comma only (tracking paren depth so e.g. Map(String, Decimal(10, 2)) isn't split on the inner comma).

Parses ClickHouse's Nullable(T) wrapper syntax, returning the inner type string.

Parses ClickHouse's Variant(T1, ..., Tn) syntax, returning {:ok, [type_string]} with the alternatives in the order they appear in the type name -- which is exactly the order the wire discriminator byte indexes into (ClickHouse normalizes a Variant's alternatives into sorted order when it resolves the type, so the name as reported on the wire is authoritative, not the order originally written in DDL).

Splits inner on its top-level comma(s) only, tracking paren depth so a parameterized inner type's own comma (e.g. the Decimal(10, 2) inside Map(String, Decimal(10, 2))) is never mistaken for the wrapper's own separator. Returns the list of (untrimmed) parts, or :error if the parens are unbalanced.

Strips a Prefix(...) wrapper down to its inner contents, given the exact "Prefix(" (including the opening paren) to match against. Not a general parenthesis-balancer -- just strips the given prefix and the trailing ) -- but that's sufficient even for a parameterized inner type like Nullable(DateTime(3)), since the outer ) is always the last byte of the whole type string.

Functions

parse_array(type)

Parses ClickHouse's Array(T) wrapper syntax, returning the inner type string.

parse_datetime64(arg1)

Parses ClickHouse's DateTime64(P) and DateTime64(P, 'Timezone') types, returning {:ok, precision}.

The timezone argument is deliberately discarded: it only affects how ClickHouse displays and parses the value, never the stored tick count, which is always an offset from the (timezone-agnostic) Unix epoch. Decoding therefore only needs the precision.

parse_decimal(arg1)

Parses Decimal(P, S) and the Decimal32(S)/Decimal64(S)/ Decimal128(S)/Decimal256(S) fixed-precision aliases, returning {:ok, precision, scale}.

parse_fixed_string(arg1)

Parses ClickHouse's FixedString(N) type, returning {:ok, n}.

parse_low_cardinality(type)

Parses ClickHouse's LowCardinality(T) wrapper syntax, returning the inner type string.

parse_map(type)

Parses ClickHouse's Map(K, V) wrapper syntax, returning {:ok, key_type, value_type}. Splits on the top-level comma only (tracking paren depth so e.g. Map(String, Decimal(10, 2)) isn't split on the inner comma).

parse_nullable(type)

Parses ClickHouse's Nullable(T) wrapper syntax, returning the inner type string.

parse_variant(type)

Parses ClickHouse's Variant(T1, ..., Tn) syntax, returning {:ok, [type_string]} with the alternatives in the order they appear in the type name -- which is exactly the order the wire discriminator byte indexes into (ClickHouse normalizes a Variant's alternatives into sorted order when it resolves the type, so the name as reported on the wire is authoritative, not the order originally written in DDL).

Splits on top-level commas only, so a parameterized alternative like Variant(Int32, Decimal(10, 2)) isn't split on the inner comma.

split_top_level_comma(inner)

Splits inner on its top-level comma(s) only, tracking paren depth so a parameterized inner type's own comma (e.g. the Decimal(10, 2) inside Map(String, Decimal(10, 2))) is never mistaken for the wrapper's own separator. Returns the list of (untrimmed) parts, or :error if the parens are unbalanced.

strip_wrapper(type, prefix)

Strips a Prefix(...) wrapper down to its inner contents, given the exact "Prefix(" (including the opening paren) to match against. Not a general parenthesis-balancer -- just strips the given prefix and the trailing ) -- but that's sufficient even for a parameterized inner type like Nullable(DateTime(3)), since the outer ) is always the last byte of the whole type string.