Aggregate functions
On this page
Per-group accumulation: update, combine, finalize.
struct AggregateBindParams
Section titled âstruct AggregateBindParamsâtype AggregateBindParams struct {Args *ArgumentsInputSchema *arrow.SchemaSettings map[string]interface{}Secrets map[string]map[string]interface{}Auth *vgirpc.AuthContext}Description
AggregateBindParams holds the parameters passed to AggregateFunction.OnBind.
interface AggregateFunction
Section titled âinterface AggregateFunctionâtype AggregateFunction interface {// Name is the SQL-visible function name.Name() string// Metadata describes function attributes (stability, null-handling, etc.).Metadata() FunctionMetadata// ArgumentSpecs declares the input columns and any const params.ArgumentSpecs() []ArgSpec// OnBind resolves the output schema. Must return a single-column schema.OnBind(params *AggregateBindParams) (*BindResponse, error)// NewState returns a fresh state pointer for a new group. The pointer// type is what the dispatcher uses for gob register/serialize.NewState(params *AggregateProcessParams) interface{}// Update accumulates rows into per-group state. The states map is// pre-populated with existing states, but groups that aren't yet in// the map MUST be created on demand by the function â call NewState// only when the row genuinely contributes (e.g. non-null value with// NullHandlingDefault). Groups never inserted into states stay absent// from storage so finalize() returns NULL.Update(states map[int64]interface{}, groupIDs *Int64Slice, columns []arrow.Array, params *AggregateProcessParams) error// Combine merges source into target, returning the new target state.Combine(source, target interface{}, params *AggregateProcessParams) (interface{}, error)// Finalize produces one result row per group_id. groupIDs entries map// to states[gid] which may be nil if the group was never updated// (NULL-only inputs with NullHandlingDefault).Finalize(groupIDs []int64, states map[int64]interface{}, params *AggregateProcessParams) (arrow.RecordBatch, error)}Description
AggregateFunction is the interface every aggregate implements.
State is held on the worker side keyed by group_id; the Go SDK
gob-serializes it across RPCs for cross-call continuity. Implementations
register a concrete state type via NewState (returning a fresh zero
value) so the dispatcher can reflect on it.
struct AggregateProcessParams
Section titled âstruct AggregateProcessParamsâtype AggregateProcessParams struct {Args *ArgumentsOutputSchema *arrow.SchemaSettings map[string]interface{}Secrets map[string]map[string]interface{}Auth *vgirpc.AuthContext// AttachOpaqueData is the catalog the function was invoked under (nil for ad-hoc calls).AttachOpaqueData []byte}Description
AggregateProcessParams is shared by Update/Combine/Finalize/Window callbacks.
interface AggregateWindowFunction
Section titled âinterface AggregateWindowFunctionâtype AggregateWindowFunction interface {AggregateFunction// WindowInit can derive optional per-partition state. Returns nil if// no derived state is needed; otherwise the value is gob-serialized// and passed back to Window.WindowInit(partition *WindowPartition, params *AggregateProcessParams) (interface{}, error)// Window computes the aggregate value for one output row.// Subframes are usually a single (begin,end) pair; up to 3 for// EXCLUDE TIES/GROUP. Returns a Go scalar matching the output schema.Window(rid int64, subframes [][2]int64, partition *WindowPartition, windowState interface{}, params *AggregateProcessParams) (interface{}, error)}Description
AggregateWindowFunction is implemented by aggregates that also support SQL OVER windowing. Functions opt in by also setting Metadata.SupportsWindow.
struct Int64Slice
Section titled âstruct Int64Sliceâtype Int64Slice struct {Data []int64}Description
Int64Slice wraps an int64 slice to ease passing to Update without importing arrow types in user code. The underlying array is borrowed.
Methods
method At
Section titled âmethod Atâfunc (s *Int64Slice) At(i int) int64At returns the i-th entry.
method Len
Section titled âmethod Lenâfunc (s *Int64Slice) Len() intLen returns the number of entries.
interface StreamingAggregateFunction
Section titled âinterface StreamingAggregateFunctionâtype StreamingAggregateFunction interface {AggregateFunction// StreamingOpen prepares cross-partition state for the session. The// returned value is opaque to the framework â it's threaded back into// StreamingChunk and StreamingClose.StreamingOpen(params *AggregateProcessParams) (interface{}, error)// StreamingChunk processes one input chunk. Implementations must return// an arrow.Array of the same length as `chunk.NumRows()`. The first// `partitionKeyCount` columns of `chunk` are the partition keys; the// next `orderKeyCount` are order keys; remaining columns are the// function's value arguments.StreamingChunk(state interface{}, chunk arrow.RecordBatch, partitionKeyCount, orderKeyCount int, params *AggregateProcessParams) (arrow.Array, error)// StreamingClose drops the session. Always called once per execution_id.StreamingClose(state interface{}, params *AggregateProcessParams) error}Description
StreamingAggregateFunction is the optional interface an aggregate may implement to participate in DuckDBâs streaming-window optimizer rule. When eligible (cumulative frame, no EXCLUDE/DISTINCT/FILTER), DuckDB pipes input chunks to the worker and expects an output array of the same length as the input.
Functions that donât implement this still work as windowed aggregates via the standard aggregate_window callbacks; the streaming path is purely an optimization.
struct WindowPartition
Section titled âstruct WindowPartitionâtype WindowPartition struct {// Inputs is the partition's input columns (excludes reserved group_id).Inputs arrow.RecordBatch// RowCount is the number of rows in the partition.RowCount int64// FilterMask is a per-row boolean from FILTER (WHERE ...); nil when absent.FilterMask []bool// FrameStats is the optimizer's per-partition frame statistics:// ((begin_delta, end_delta), (begin_delta, end_delta)).FrameStats [2][2]int64// AllValid[i] is true if input column i has no nulls.AllValid []bool// OutputSchema is the function's resolved output schema.OutputSchema *arrow.Schema}Description
WindowPartition is the partition data available during windowed evaluation.
Methods
function unpackWindowPartition
Section titled âfunction unpackWindowPartitionâfunc unpackWindowPartition(req AggregateWindowInitRequestWire) (*WindowPartition, error)struct aggregateStorage
Section titled âstruct aggregateStorageâtype aggregateStorage struct {mu sync.Mutexback FunctionStorageresolve func() (FunctionStorage, error) // set by the Worker}Description
aggregateStorage is a thin shim that lazily resolves a FunctionStorage backend from a setter and exposes the bucket(funcName, execID) pattern the protocol layer uses.
Methods
method bucket
Section titled âmethod bucketâfunc (s *aggregateStorage) bucket(funcName string, execID []byte, shardKey string) *stateBucketmethod ensureOpen
Section titled âmethod ensureOpenâfunc (s *aggregateStorage) ensureOpen() (FunctionStorage, error)ensureOpen resolves and caches the backend on first use.
function newAggregateStorage
Section titled âfunction newAggregateStorageâfunc newAggregateStorage() *aggregateStoragemethod setResolver
Section titled âmethod setResolverâfunc (s *aggregateStorage) setResolver(r func() (FunctionStorage, error))setResolver wires a lazy backend resolver. Called once by the Worker so the FunctionStorage is shared with ExecutionStorage and any future backends (Cloudflare DO, etc.).
struct stateBucket
Section titled âstruct stateBucketâtype stateBucket struct {storage *aggregateStoragefunctionName stringexecutionID []byte// shardKey routes per logical ATTACH (att-<hex uuid>) for the CfDo backend;// "" for non-sharding backends. Derived by the handler from the request's// unwrapped attach UUID.shardKey string}Description
stateBucket binds aggregate operations to one (function_name, execution_id). Mirrors the original surface so aggregate_protocol.go and aggregate_helpers.go donât have to change.
Methods
method backend
Section titled âmethod backendâfunc (b *stateBucket) backend() (FunctionStorage, error)backend resolves the shared backend and, for a remote-sharding backend (CfDo), pins it to this bucketâs shard key â so aggregate state routes to the same Durable Object as the executionâs other storage.
method clear
Section titled âmethod clearâfunc (b *stateBucket) clear() errorclear drops aggregate state and window partition rows for this execution_id. Const args are intentionally left behind: theyâre small, keyed by (execution_id, function_name), and reaped by the FunctionStorageâs TTL sweep. Matches vgi-python which also has no per-call const-args clear.
method deleteWindowPartition
Section titled âmethod deleteWindowPartitionâfunc (b *stateBucket) deleteWindowPartition(partitionID int64) errormethod getConstArgs
Section titled âmethod getConstArgsâfunc (b *stateBucket) getConstArgs() ([]byte, error)method getWindowPartition
Section titled âmethod getWindowPartitionâfunc (b *stateBucket) getWindowPartition(partitionID int64) ([]byte, error)method loadStates
Section titled âmethod loadStatesâfunc (b *stateBucket) loadStates(gids []int64) (map[int64][]byte, error)loadStates fetches all states for the given group_ids. Returns a map keyed by group_id; gids absent from the result are not yet stored. Matches the pre-shared-backend surface so callers donât change.
method putConstArgs
Section titled âmethod putConstArgsâfunc (b *stateBucket) putConstArgs(args []byte) errormethod putWindowPartition
Section titled âmethod putWindowPartitionâfunc (b *stateBucket) putWindowPartition(partitionID int64, payload []byte) errormethod saveStates
Section titled âmethod saveStatesâfunc (b *stateBucket) saveStates(states map[int64][]byte) errorsaveStates writes (gid, bytes) pairs.
struct streamingSession
Section titled âstruct streamingSessionâtype streamingSession struct {fn StreamingAggregateFunctionstate interface{}outputSchema *arrow.SchemapartitionKeyCount intorderKeyCount intargs *Argumentssettings map[string]interface{}secrets map[string]map[string]interface{}attachOpaqueData []byte}Description
streamingSession holds per-execution_id state for a streaming-aggregate invocation. The session is removed in handleAggregateStreamingClose.
struct streamingSessionStore
Section titled âstruct streamingSessionStoreâtype streamingSessionStore struct {mu sync.Mutexsessions map[string]*streamingSession}Methods
method drop
Section titled âmethod dropâfunc (s *streamingSessionStore) drop(execID []byte) *streamingSessionmethod get
Section titled âmethod getâfunc (s *streamingSessionStore) get(execID []byte) *streamingSessionmethod put
Section titled âmethod putâfunc (s *streamingSessionStore) put(execID []byte, sess *streamingSession)struct windowPartitionPayload
Section titled âstruct windowPartitionPayloadâtype windowPartitionPayload struct {PartitionBatch []byteOutputSchema []byteFilterMask []byteFrameStats []byteAllValid []byteRowCount int64WindowState []byte // optional gob-encoded WindowInit return value}Methods
function decodeWindowPartitionPayload
Section titled âfunction decodeWindowPartitionPayloadâfunc decodeWindowPartitionPayload(data []byte) (windowPartitionPayload, error)function EnsureState
Section titled âfunction EnsureStateâfunc EnsureState[T any](states map[int64]interface{}, gid int64, newFn func() *T) *TEnsureState is a helper for Update implementations: returns the existing state for gid, or creates one via newFn() and registers it. Functions should call this only when the row genuinely contributes (e.g. non-null with NullHandlingDefault) â groups never inserted stay absent from storage so finalize() returns NULL.
function PartitionKey
Section titled âfunction PartitionKeyâfunc PartitionKey(chunk arrow.RecordBatch, partitionKeyCount, i int) uint64PartitionKey is a helper to derive a stable hash key from the partition-key columns at row i. Use it from StreamingChunk implementations to look up per-partition state.
function buildBatchResult
Section titled âfunction buildBatchResultâfunc buildBatchResult(values []interface{}, outputSchema *arrow.Schema) (arrow.RecordBatch, error)buildBatchResult builds a count-row RecordBatch from a slice of scalar values.
function buildScalarColumn
Section titled âfunction buildScalarColumnâfunc buildScalarColumn(mem memory.Allocator, dt arrow.DataType, values []interface{}) (arrow.Array, error)buildScalarColumn appends each value (or null) into a column of the given type.
function buildScalarResultBatch
Section titled âfunction buildScalarResultBatchâfunc buildScalarResultBatch(value interface{}, outputSchema *arrow.Schema) (arrow.RecordBatch, error)buildScalarResultBatch wraps a single scalar value in a one-row RecordBatch matching outputSchema (which must have exactly one field).
function buildSingleScalarArray
Section titled âfunction buildSingleScalarArrayâfunc buildSingleScalarArray(mem memory.Allocator, dt arrow.DataType, v interface{}) (arrow.Array, error)function encodeWindowPartitionPayload
Section titled âfunction encodeWindowPartitionPayloadâfunc encodeWindowPartitionPayload(req AggregateWindowInitRequestWire, windowState []byte) []bytefunction gobDecodeState
Section titled âfunction gobDecodeStateâfunc gobDecodeState(data []byte) (interface{}, error)gobDecodeState deserializes bytes into a state value via gobâs interface machinery. The concrete type must have been previously registered with gob.Register.
function gobEncodeState
Section titled âfunction gobEncodeStateâfunc gobEncodeState(state interface{}) ([]byte, error)gobEncodeState serializes a state value (passed by interface, typically a pointer to a registered struct) to bytes.
function splitGroupIDColumn
Section titled âfunction splitGroupIDColumnâfunc splitGroupIDColumn(batch arrow.RecordBatch) (int, []int64, []arrow.Array, error)splitGroupIDColumn returns the group_id column index, the int64 group_ids, and the remaining input columns (excluding group_id).
function uniqueInt64
Section titled âfunction uniqueInt64âfunc uniqueInt64(in []int64) []int64function unpackAllValid
Section titled âfunction unpackAllValidâfunc unpackAllValid(data []byte, numCols int) []boolunpackAllValid reads numCols bytes â one per input column â into a []bool.
function unpackBoolMask
Section titled âfunction unpackBoolMaskâfunc unpackBoolMask(packed []byte, rowCount int64) []boolunpackBoolMask converts the C++ extensionâs packed-bit boolean encoding into a flat []bool of length rowCount.
function unpackFrameStats
Section titled âfunction unpackFrameStatsâfunc unpackFrameStats(data []byte) [2][2]int64unpackFrameStats reads ((begin_delta, end_delta), (begin_delta, end_delta)) from 4Ăint64 little-endian bytes.