AshClickhouse.DataLayer.Types (AshClickhouse v0.4.0)

Copy Markdown View Source

Mapping between Ash attribute types and ClickHouse column types.

ClickHouse is a strongly-typed columnar store. When generating CREATE TABLE statements and when encoding query parameters, the data layer needs to know the ClickHouse type that corresponds to each Ash attribute.

The mapping here favours ClickHouse types that are safe and broadly useful:

Ash typeClickHouse type
:uuidUUID
:string / :atom / :ci_stringString
:integerInt64
:floatFloat64
:booleanUInt8
:utc_datetime / :naive_datetimeDateTime / DateTime64
:dateDate
:timeString
:decimalDecimal
:mapMap(String, String)
:array / :listArray(String)

Summary

Functions

Maps an Ash attribute type to a ClickHouse column type string.

Returns the set of attribute names (atom) that are Atom-typed.

Builds a map of attribute name => ClickHouse type string for a resource.

Converts a single parameter to its 16-byte UUID binary form only when the column it belongs to is known to be UUID-typed. This replaces the old convert_uuid_params/2 heuristic that mangled any 36-character string that merely looked like a UUID — including legitimate :string business identifiers (order numbers, etc.).

Decodes a raw ClickHouse value back into its Ash attribute value.

Encodes an Ash attribute value into a ClickHouse-bindable value.

Formats the five 16-byte UUID segments into a canonical 36-character (lowercase) UUID string.

Resolves the ClickHouse type for an Ash attribute struct, preferring the attribute's storage_type/1 when available.

Returns the set of attribute names (atom and string) that are UUID-typed.

Converts a 16-byte UUID binary to its canonical 36-character string form.

Returns true if the given binary looks like a canonical UUID string.

Converts a 36-character UUID string to its 16-byte binary form for ClickHouse.

Functions

ash_type_to_clickhouse(type)

@spec ash_type_to_clickhouse(atom() | tuple() | module()) :: String.t()

Maps an Ash attribute type to a ClickHouse column type string.

atom_attribute_names(resource)

@spec atom_attribute_names(module()) :: MapSet.t(atom())

Returns the set of attribute names (atom) that are Atom-typed.

attr_type_map(resource)

@spec attr_type_map(module()) :: %{required(atom() | String.t()) => String.t()}

Builds a map of attribute name => ClickHouse type string for a resource.

convert_uuid_param(value, column, uuid_fields)

@spec convert_uuid_param(term(), term(), MapSet.t()) :: term()

Converts a single parameter to its 16-byte UUID binary form only when the column it belongs to is known to be UUID-typed. This replaces the old convert_uuid_params/2 heuristic that mangled any 36-character string that merely looked like a UUID — including legitimate :string business identifiers (order numbers, etc.).

decode_value(value, attr)

@spec decode_value(term(), map()) :: term()

Decodes a raw ClickHouse value back into its Ash attribute value.

Mirrors encode_value/2: stringified maps/lists are left as-is (the ClickHouse client already returns them in the expected shape for the Map(String, String) / Array(String) column types), and time strings are parsed back into Time structs.

encode_value(value, attr)

@spec encode_value(term(), map()) :: term()

Encodes an Ash attribute value into a ClickHouse-bindable value.

Most types pass through unchanged, but ClickHouse-specific encodings are applied where the raw Elixir value would not bind correctly:

  • :map / {:map, _, _} — keys and values stringified (ClickHouse's Map(String, String) representation).
  • :array / :list / {:array, _} — elements stringified for the Array(String) representation.
  • :time / :time_usecTime converted to its "HH:MM:SS" string.
  • :decimalDecimal passed through (the client encodes it).

format_uuid_string(a, b, c, d, e)

@spec format_uuid_string(integer(), integer(), integer(), integer(), integer()) ::
  String.t()

Formats the five 16-byte UUID segments into a canonical 36-character (lowercase) UUID string.

resolve_attr_type(attr)

@spec resolve_attr_type(map()) :: String.t()

Resolves the ClickHouse type for an Ash attribute struct, preferring the attribute's storage_type/1 when available.

uuid_attribute_names(resource)

@spec uuid_attribute_names(module()) :: MapSet.t()

Returns the set of attribute names (atom and string) that are UUID-typed.

uuid_binary_to_string(value)

@spec uuid_binary_to_string(binary()) :: {:ok, String.t()} | :error

Converts a 16-byte UUID binary to its canonical 36-character string form.

uuid_like_string?(value)

@spec uuid_like_string?(term()) :: boolean()

Returns true if the given binary looks like a canonical UUID string.

uuid_string_to_binary(value)

@spec uuid_string_to_binary(String.t()) :: {:ok, binary()} | :error

Converts a 36-character UUID string to its 16-byte binary form for ClickHouse.