From ea3be3a9cf19e08a1e6f5a684f7fcbb6cdb715cf Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Thu, 10 May 2012 14:35:54 +0200 Subject: [PATCH] CData: Added cdata_update(). This function may be used to update an existing data set by "merging" another data set according to the consolidation function. --- src/cdata.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ src/postrr.h.in | 4 ++++ src/postrr.sql.in | 5 +++++ 3 files changed, 62 insertions(+) diff --git a/src/cdata.c b/src/cdata.c index b47e3f8..32e8e4d 100644 --- a/src/cdata.c +++ b/src/cdata.c @@ -80,6 +80,8 @@ PG_FUNCTION_INFO_V1(cdata_typmodout); PG_FUNCTION_INFO_V1(cdata_to_cdata); PG_FUNCTION_INFO_V1(int32_to_cdata); +PG_FUNCTION_INFO_V1(cdata_update); + /* * public API */ @@ -329,5 +331,56 @@ int32_to_cdata(PG_FUNCTION_ARGS) PG_RETURN_CDATA_P(data); } /* int32_to_cdata */ +Datum +cdata_update(PG_FUNCTION_ARGS) +{ + cdata_t *data; + cdata_t *update; + + if (PG_NARGS() != 2) + ereport(ERROR, ( + errmsg("cdata_update() expects two arguments"), + errhint("Usage: cdata_update(cdata, cdata)") + )); + + data = PG_GETARG_CDATA_P(0); + update = PG_GETARG_CDATA_P(1); + + if ((data->cf != update->cf) && (update->val_num > 1)) + ereport(ERROR, ( + errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid update value: incompatible " + "consolidation function") + )); + + switch (data->cf) { + case CF_AVG: + data->value = (data->value * (data->val_num - data->undef_num)) + + (update->value * (update->val_num - update->undef_num)); + data->value /= (data->val_num - data->undef_num) + + (update->val_num - update->undef_num); + break; + case CF_MIN: + data->value = (data->value <= update->value) + ? data->value : update->value; + break; + case CF_MAX: + data->value = (data->value >= update->value) + ? data->value : update->value; + break; + default: + ereport(ERROR, ( + errcode(ERRCODE_DATA_CORRUPTED), + errmsg("unknown consolidation function %d", + data->cf) + )); + break; + } + + data->undef_num += update->undef_num; + data->val_num += update->val_num; + PG_RETURN_CDATA_P(data); +} /* cdata_update */ + /* vim: set tw=78 sw=4 ts=4 noexpandtab : */ diff --git a/src/postrr.h.in b/src/postrr.h.in index bca014a..c309ef0 100644 --- a/src/postrr.h.in +++ b/src/postrr.h.in @@ -135,6 +135,10 @@ cdata_to_cdata(PG_FUNCTION_ARGS); Datum int32_to_cdata(PG_FUNCTION_ARGS); +/* aux. functions */ +Datum +cdata_update(PG_FUNCTION_ARGS); + #endif /* ! POSTRR_H */ /* vim: set tw=78 sw=4 ts=4 noexpandtab : */ diff --git a/src/postrr.sql.in b/src/postrr.sql.in index ed51ab6..9339e32 100644 --- a/src/postrr.sql.in +++ b/src/postrr.sql.in @@ -280,6 +280,11 @@ CREATE CAST (integer AS cdata) WITH FUNCTION CData(integer, integer, boolean) AS ASSIGNMENT; +CREATE OR REPLACE FUNCTION CData_update(cdata, cdata) + RETURNS cdata + AS 'postrr-@POSTRR_MAJOR_VERSION@.@POSTRR_MINOR_VERSION@', 'cdata_update' + LANGUAGE 'C' IMMUTABLE STRICT; + COMMIT; SET client_min_messages TO DEFAULT; -- 2.30.2