clickhouse/clickhouse
Aggregate functions
src/AggregateFunctions/ is the registry of aggregate functions and their states. Aggregates are different from scalar functions: they have an internal state that is updated row-by-row, can be merged across threads or shards, and is finally serialized into a single value (or another column).
Architecture
Each aggregate is a class implementing IAggregateFunction (src/AggregateFunctions/IAggregateFunction.h). Key methods:
create(place)/destroy(place)— initialize / tear down state at a memory address.add(place, columns, row_num, arena)— incorporate one row.merge(place_left, place_right, arena)— merge two states.serialize(place, buf, arena)/deserialize(place, buf, arena)— disk/wire serialization.insertResultInto(place, to, arena)— produce the final value into an output column.- Optional vectorized
addBatch*,mergeBatch,addManyDefaultsfor hot-path optimization.
Aggregates register via AggregateFunctionFactory (src/AggregateFunctions/AggregateFunctionFactory.cpp).
Catalog
| Family | Functions |
|---|---|
| Counts | count, count(distinct), nullableCount |
| Sums | sum, sumWithOverflow, sumKahan, sumMap, sumIf, sumOrNull |
| Min/max | min, max, argMin, argMax, any, anyLast, anyHeavy |
| Statistics | avg, avgWeighted, varSamp, varPop, stddevSamp, stddevPop, corr, covarSamp, covarPop, median*, quantile* (10+ variants), entropy, kolmogorovSmirnovTest, mannWhitneyUTest, studentTTest |
| Sketches | uniq, uniqExact, uniqCombined, uniqHLL12, uniqTheta, quantileTDigest, quantileGK, groupBitmap, topK, theilsU, cramersV |
| Group ops | groupArray, groupUniqArray, groupBitmap*, groupArraySample, groupArrayMovingSum, arrayConcatAgg |
| Sequence | windowFunnel, sequenceCount, sequenceMatch, retention, analysisOfVariance |
| Categorical | categoricalInformationValue, entropy |
| ML | simpleLinearRegression, stochasticLinearRegression, stochasticLogisticRegression |
| Streaming | intervalLengthSum, largestTriangleThreeBuckets, deltaSum, deltaSumTimestamp, last_value, first_value, boundingRatio |
| Geo | largestTriangleThreeBuckets |
| Numeric vector | groupArrayInsertAt, groupArrayLast, numericIndexedVector |
| Combinators | *If, *Array, *Merge, *State, *Distinct, *ForEach, *OrDefault, *OrNull, *Resample, *SimpleState, *Map |
The combinator infrastructure lives under src/AggregateFunctions/Combinators/. A combinator wraps another aggregate to implement modifiers — e.g. sumIf(x, cond) is If over sum, quantilesArray(...) is Array over quantiles, sumMerge(state) is Merge over sum.
State machinery
States live in arenas (src/Common/Arena.h) so they can be vector-allocated and freed in bulk. Variable-size states (e.g. topK, groupArray) reference arena buffers via offsets to avoid per-state heap allocations.
AggregateDataPtr is just char * pointing at a state. The aggregate function knows its state's size and alignment via sizeOfData() and alignOfData().
Two-phase aggregation
Aggregator (in src/Interpreters/) reads input rows, picks the right hash-table layout for the key, and per row calls add(place, ...). When several threads aggregate, each thread has its own hash table. In the merge phase, two-level hashing distributes states by key into buckets, each merged independently — merge(left, right) is exactly the operation needed.
*State and *Merge combinators
These implement the on-disk representation of partial aggregation:
sumState(...)returns the state ofsuminstead of the final value, in a column of typeAggregateFunction(sum, ...).sumMerge(state_column)consumes such states and produces final values.
This is what makes AggregatingMergeTree and Materialized Views work — partial states are persisted, merged across batches, and finalized only at read time.
Adding an aggregate
- Write a class subclassing
IAggregateFunctionDataHelper<...>(orIAggregateFunctionHelper). - Implement
add,merge,serialize,deserialize,insertResultInto. - Register via
void registerAggregateFunctionFoo(AggregateFunctionFactory & factory)and call it fromregisterAggregateFunctions.cpp. - Tests under
tests/queries/0_stateless/.
The combinator system is opt-in via per-function declarations (isStateful(), getDefaultVersion(), etc.).
Related pages
- Functions
- Data types and columns — the
AggregateFunction(name, args)data type. - Interpreters —
AggregatorandAggregatedDataVariants. - Materialized views — typical consumer of
*Stateaggregates.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.