Code

CData: Added cdata_update().
authorSebastian Harl <sh@tokkee.org>
Thu, 10 May 2012 12:35:54 +0000 (14:35 +0200)
committerSebastian 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.

src/cdata.c
src/postrr.h.in
src/postrr.sql.in

index b47e3f87d169a107f63177df503192e3c6b722fb..32e8e4d0b8dbad51c5ec428d95b70543faefeca6 100644 (file)
@@ -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 : */
 
index bca014a9d47591294dd7dfb4702ee9dfb7c2d3ab..c309ef04ebb68146194c1d59f83a2b5961b6494f 100644 (file)
@@ -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 : */
index ed51ab676f2de477039986a248bcbde81c482bf8..9339e32f04ed948fc374e182d40311c999628054 100644 (file)
@@ -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;