Escape
HomeDocsFunctions and reducers

Functions and reducers

Two kinds of function are callable without registering anything. A registered host function of the same name shadows either.

Aggregate reducers

Declared under aggregates on the report or on a group.

Reducer Result Empty
sum:=expr total of expr 0
count number of rows 0
countDistinct:=expr distinct values of expr 0
avg:=expr mean of expr null
min:=expr smallest expr null
max:=expr largest expr null

count takes no expression. Every other reducer takes the form name:=expression. Give avg, min and max a visible marker where an empty set matters.

Run reducers

Declared under run, and read as run.<name> on a detail row. The six above, plus one.

Reducer run.<name> on each row
sum:=expr cumulative sum up to and including this row
count 1-based running count
countDistinct:=expr distinct values seen so far
avg:=expr cumulative mean so far
min:=expr, max:=expr running extreme so far
prev:=expr expr of the previous row, null on the first

Scope decides the reset. A run block on the report persists across the document. A run block on a group starts again at each instance. Run names can’t repeat across the report and nested groups, because every run value shares one run object.

Scalar built-ins

One value in, one value out. These are function calls only, never a reducer declaration, so "total": "round:[email protected]" is a definition error.

Function Result
round(x, n?) x to n decimal places, halves away from zero
floor(x, n?) x to n decimal places, towards negative infinity
ceil(x, n?) x to n decimal places, towards positive infinity
abs(x) the magnitude of x

They round the decimal you wrote, not the double it’s stored as, so round(2.675, 2) is 2.68.

n defaults to 0 and must be a number from 0 to 100. A fractional n truncates to whole places. Anything outside that’s an error naming the cell and the call. A non-finite x passes through untouched rather than folding to zero.

min and max are reducer names and aren’t scalar two-argument functions. min(1, 2) is a render error saying so. trunc isn’t built in.

Inline reducers

A reducer also folds an array on the row itself.

an inline reducer
{ "value": "{{ sum(@.lines, l => l.total) }}" }

Registered functions

signature
type FunctionRegistry = Record<string, (...args: any[]) => any>

Passed as the second argument to report or plan. Registered functions count as trusted configuration, the same standing as the definition. A compiled report lists the ones it calls on report.functions, each as a { name, arity, doc? } signature in call-first-seen order.

What an expression may call.

npm install quario
Getting started
© 2026 quario · KvK 61815977