summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 26fb850)
raw | patch | inline | side by side (parent: 26fb850)
author | Sebastian Harl <sh@tokkee.org> | |
Thu, 10 May 2012 12:35:54 +0000 (14:35 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Thu, 10 May 2012 12:35:54 +0000 (14:35 +0200) |
This function may be used to update an existing data set by "merging" another
data set according to the consolidation function.
data set according to the consolidation function.
src/cdata.c | patch | blob | history | |
src/postrr.h.in | patch | blob | history | |
src/postrr.sql.in | patch | blob | history |
diff --git a/src/cdata.c b/src/cdata.c
index b47e3f87d169a107f63177df503192e3c6b722fb..32e8e4d0b8dbad51c5ec428d95b70543faefeca6 100644 (file)
--- a/src/cdata.c
+++ b/src/cdata.c
PG_FUNCTION_INFO_V1(cdata_to_cdata);
PG_FUNCTION_INFO_V1(int32_to_cdata);
+PG_FUNCTION_INFO_V1(cdata_update);
+
/*
* public API
*/
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 bca014a9d47591294dd7dfb4702ee9dfb7c2d3ab..c309ef04ebb68146194c1d59f83a2b5961b6494f 100644 (file)
--- a/src/postrr.h.in
+++ b/src/postrr.h.in
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 ed51ab676f2de477039986a248bcbde81c482bf8..9339e32f04ed948fc374e182d40311c999628054 100644 (file)
--- a/src/postrr.sql.in
+++ b/src/postrr.sql.in
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;