NAME
DBIO::ClickHouse::Result - ClickHouse-specific Result component for DBIO
VERSION
version 0.900004
DESCRIPTION
DBIO::ClickHouse::Result is a DBIO Result component that adds the ClickHouse-native table metadata a CREATE TABLE cannot do without: the table engine and the MergeTree sorting key, plus the optional partition key, primary key and engine settings. It is the counterpart to DBIO::MySQL::Result / DBIO::PostgreSQL::Result and is read by DBIO::ClickHouse::DDL when generating install DDL.
Load it with:
package MyApp::DB::Result::Event;
use base 'DBIO::Core';
__PACKAGE__->load_components('ClickHouse::Result');
__PACKAGE__->table('events');
__PACKAGE__->add_columns(
id => { data_type => 'uuid', is_auto_increment => 1 },
ts => { data_type => 'datetime', is_nullable => 0 },
name => { data_type => 'varchar', is_nullable => 0,
extra => { low_cardinality => 1 } },
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->clickhouse_table({
engine => 'ReplacingMergeTree(ts)',
order_by => ['ts', 'id'],
partition_by => 'toYYYYMM(ts)',
settings => { index_granularity => 8192 },
});
Why a Result component
The alternatives were a table_class override and a bare class accessor on the result class. A Result component is what the rest of the family already uses for driver-native table metadata (mysql_engine, pg_schema, sqlite_index), it is opt-in per result class, and it keeps the DDL layer's contract to a single duck-typed method call. DBIO::ClickHouse::DDL reads the options through $result_class->can('clickhouse_table'), so a schema that never loads this component is not broken by its absence -- every table simply gets the default ENGINE = MergeTree with ORDER BY = primary key.
METHODS
clickhouse_table
__PACKAGE__->clickhouse_table({
engine => 'MergeTree',
order_by => ['ts', 'id'],
primary_key => ['ts'],
partition_by => 'toYYYYMM(ts)',
settings => { index_granularity => 8192 }
});
my $opts = $class->clickhouse_table;
Get or set this result class's ClickHouse table options. Returns a shallow copy of the stored options, or undef when none were declared. Recognised keys:
engine-
The table engine, emitted verbatim after
ENGINE =, so parameterized engines work ('ReplacingMergeTree(version)'). Defaults toMergeTreein the generated DDL when unset. order_by-
The MergeTree sorting key, as a column name or an arrayref of them. Entries are quoted as identifiers; pass a SCALAR ref for a raw expression (
\'cityHash64(id)'). Defaults to the result class's primary key. An explicit empty arrayref rendersORDER BY tuple(), ClickHouse's spelling for "no sorting key".Note that in ClickHouse the sorting key is the primary key -- there is no separate index structure, and no uniqueness is implied or enforced.
primary_key-
Only needed when the primary key should be a strict prefix of
order_by(a coarser index over a finer sort order). Same value shape asorder_by. When omitted,ORDER BYalone defines the primary key, which is also how ClickHouse renders it back. partition_by-
A partition-key expression, emitted verbatim (
'toYYYYMM(ts)'). It is not quoted as an identifier, because a partition key is nearly always a function call. settings-
Engine settings as a hashref. Names are emitted bare and sorted; numeric-looking values are emitted bare, SCALAR refs verbatim, everything else quoted.
TTL and SAMPLE BY are not modelled yet.
Invalid options are rejected at class-definition time through throw_exception, so a typo fails when the result class is compiled rather than when the DDL is deployed.
SEE ALSO
DBIO::ClickHouse::DDL - consumes
clickhouse_tableDBIO::MySQL::Result - the MySQL counterpart
AUTHOR
DBIO Authors
COPYRIGHT AND LICENSE
Copyright (C) 2026 DBIO Authors
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.