1) Sigma calculation had an error. The first data value in each bin didn't get squared.
[rrdtool.git] / src / rrd_fetch_libdbi.c
index 0e8bc93..b4f0fc7 100644 (file)
@@ -1,4 +1,5 @@
 #include "rrd_tool.h"
+#include "unused.h"
 #include <dbi/dbi.h>
 #include <time.h>
 
@@ -365,7 +366,7 @@ static int _inline_unescape (char* string) {
 int
 rrd_fetch_fn_libdbi(
     const char     *filename,  /* name of the rrd */
-    enum cf_en     cf_idx __attribute__((unused)), /* consolidation function */
+    enum cf_en     UNUSED(cf_idx), /* consolidation function */
     time_t         *start,
     time_t         *end,       /* which time frame do you want ?
                                * will be changed to represent reality */
@@ -400,6 +401,7 @@ rrd_fetch_fn_libdbi(
   char where[10240];
   table_help.conn=NULL;
   table_help.where=where;
+  table_help.filename=filename;
 
   /* some loop variables */
   int i=0;
@@ -563,7 +565,7 @@ rrd_fetch_fn_libdbi(
   }
 
   /* allocate memory for resultset (with the following columns: min,avg,max,count,sigma) */
-  i=rows * sizeof(rrd_value_t)*(*ds_cnt);
+  i=(rows+1) * sizeof(rrd_value_t)*(*ds_cnt);
   if (((*data) = malloc(i))==NULL){
     /* and return error */
     rrd_set_error("malloc failed for %i bytes",i);
@@ -613,7 +615,7 @@ rrd_fetch_fn_libdbi(
        (*data)[idx*(*ds_cnt)+1]=r_value; /* AVG */
        (*data)[idx*(*ds_cnt)+2]=r_value; /* MAX */
        (*data)[idx*(*ds_cnt)+3]=1;       /* COUNT */
-       (*data)[idx*(*ds_cnt)+4]=r_value; /* SIGMA */
+       (*data)[idx*(*ds_cnt)+4]=r_value*r_value; /* SIGMA */
       } else {
        /* MIN */
        if ((*data)[idx*(*ds_cnt)+0]>r_value) { (*data)[idx*(*ds_cnt)+0]=r_value; }
@@ -650,6 +652,30 @@ rrd_fetch_fn_libdbi(
     }
   }
 
+  /* Fill in missing values */
+  fillmissing/=(*step);/* Convert from seconds to steps */
+  if (fillmissing>0) {
+    int copy_left=fillmissing;
+    for(idx=1;idx<rows;idx++) {
+      long count=(*data)[idx*(*ds_cnt)+3];
+      if (count==0) {
+        /* No data this bin */
+        if (copy_left>0) {
+          /* But we can copy from previous */
+          int idx_p=idx-1;
+          (*data)[idx*(*ds_cnt)+0]=(*data)[idx_p*(*ds_cnt)+0];
+          (*data)[idx*(*ds_cnt)+1]=(*data)[idx_p*(*ds_cnt)+1];
+          (*data)[idx*(*ds_cnt)+2]=(*data)[idx_p*(*ds_cnt)+2];
+          (*data)[idx*(*ds_cnt)+3]=(*data)[idx_p*(*ds_cnt)+3];
+          (*data)[idx*(*ds_cnt)+4]=(*data)[idx_p*(*ds_cnt)+4];
+          copy_left--;
+        }
+      }else{
+        copy_left=fillmissing;
+      }
+    }
+  }
+
   /* and return OK */
   return 0;
 }