timescaledb/sql/aggregates.sql
gayyappan b45343b3cc Add ability to work with aggregate partials
The ability to get aggregate partials instead of the final state
is important for both continuous aggregation and clustering.

This commit adds the ability to work with aggregate partials.
Namely a function called _timescaledb_internal.partialize_agg
can now wrap an aggregate and return the partial results as a bytea.

The _timescaledb_internal.finalize_agg aggregate allows you to combine
and finalize partials.

The partialize_agg function works as a marker in the planner to force
the planner to return partial result.

Unfortunately, we could not get the planner to modify the plan directly
to aggregate partials. Instead, the finalize_agg is a real aggregate
that performs aggregation on the partial state. Note that it is not
yet parallel.

Aggregate that use FINALFUNC_EXTRA are currently not supported.

Co-authored-by: gayyappan <gayathri@timescale.com>
Co-authored-by: David Kohn <david@timescale.com>
2019-04-12 12:12:17 -04:00

61 lines
2.7 KiB
SQL

-- This file and its contents are licensed under the Apache License 2.0.
-- Please see the included NOTICE for copyright information and
-- LICENSE-APACHE for a copy of the license.
-- This file is meant to contain aggregate functions that need to be created only
-- once and not recreated during updates.
-- There is no CREATE OR REPLACE AGGREGATE which means that the only way to replace
-- an aggregate is to DROP then CREATE which is problematic as it will fail
-- if the previous version of the aggregate has dependencies.
-- NOTE that WHEN CREATING NEW FUNCTIONS HERE you should also make sure they are
-- created in an update script so that both new users and people updating from a
-- previous version get the new function
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
--Ex. first(temp, time) returns the temp value for the row with the lowest time
CREATE AGGREGATE first(anyelement, "any") (
SFUNC = _timescaledb_internal.first_sfunc,
STYPE = internal,
COMBINEFUNC = _timescaledb_internal.first_combinefunc,
SERIALFUNC = _timescaledb_internal.bookend_serializefunc,
DESERIALFUNC = _timescaledb_internal.bookend_deserializefunc,
PARALLEL = SAFE,
FINALFUNC = _timescaledb_internal.bookend_finalfunc,
FINALFUNC_EXTRA
);
--This aggregate returns the "last" element of the first argument when ordered by the second argument.
--Ex. last(temp, time) returns the temp value for the row with highest time
CREATE AGGREGATE last(anyelement, "any") (
SFUNC = _timescaledb_internal.last_sfunc,
STYPE = internal,
COMBINEFUNC = _timescaledb_internal.last_combinefunc,
SERIALFUNC = _timescaledb_internal.bookend_serializefunc,
DESERIALFUNC = _timescaledb_internal.bookend_deserializefunc,
PARALLEL = SAFE,
FINALFUNC = _timescaledb_internal.bookend_finalfunc,
FINALFUNC_EXTRA
);
-- This aggregate partitions the dataset into a specified number of buckets (nbuckets) ranging
-- from the inputted min to max values.
CREATE AGGREGATE histogram (DOUBLE PRECISION, DOUBLE PRECISION, DOUBLE PRECISION, INTEGER) (
SFUNC = _timescaledb_internal.hist_sfunc,
STYPE = INTERNAL,
COMBINEFUNC = _timescaledb_internal.hist_combinefunc,
SERIALFUNC = _timescaledb_internal.hist_serializefunc,
DESERIALFUNC = _timescaledb_internal.hist_deserializefunc,
PARALLEL = SAFE,
FINALFUNC = _timescaledb_internal.hist_finalfunc,
FINALFUNC_EXTRA
);
CREATE AGGREGATE _timescaledb_internal.finalize_agg( TEXT, NAME, NAME, BYTEA, anyelement) (
SFUNC = _timescaledb_internal.finalize_agg_sfunc,
STYPE = internal,
FINALFUNC = _timescaledb_internal.finalize_agg_ffunc,
FINALFUNC_EXTRA
);