From d3a149efcab431c1cfe4a828a1855963dbf1a6ef Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 24 Feb 2002 17:12:53 +0000 Subject: [PATCH] Added a "stddev()" aggregate function for testing the new user aggregate function interface. (CVS 393) FossilOrigin-Name: 2198109712ccf988f93db5740a4f248e80fb9f5d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3e7fea43e5..b01eac774f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Code\sfor\suser-defined\saggregates\sadded.\s\sLegacy\stests\sall\spass\sbut\sthere\nhas\sbeen\sno\stesting\sof\sthe\snew\suser-defined\saggregate\scode.\s(CVS\s392) -D 2002-02-24T03:25:15 +C Added\sa\s"stddev()"\saggregate\sfunction\sfor\stesting\sthe\snew\suser\saggregate\nfunction\sinterface.\s(CVS\s393) +D 2002-02-24T17:12:54 F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 @@ -24,7 +24,7 @@ F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3 F src/build.c 1da051784be0155ae579d47890db74f0186f9b9f F src/delete.c 950d8f9097361419f1963875f9943344b469cf02 F src/expr.c 5ed59aed47431a540263da2ca79c37a97c23e8fd -F src/func.c f06739ac3266fe237a8079415c75b4fe27f9b604 +F src/func.c b7c1f4dd183dbca7996641017eb13bd7f820a263 F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892 F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9 F src/insert.c 164d2d5e943268a8ff0594e1947599e04df0ce11 @@ -126,7 +126,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279 F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 530b0f4f2def89e200b7b0724a5967bf981bd91d -R b1dfb8bf18a05ccd329e7446e18d18c8 +P 1e037eb303d8508cb2ea3418e71b03315d895fbd +R 21d5c48b8dddd8d019c6a58015885a64 U drh -Z 0bcdda8b20886809bb64b19128bb3b89 +Z d7e9ee595615113d0da5c9ca524c595c diff --git a/manifest.uuid b/manifest.uuid index caeaedcb00..b1cfa4d76c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e037eb303d8508cb2ea3418e71b03315d895fbd \ No newline at end of file +2198109712ccf988f93db5740a4f248e80fb9f5d \ No newline at end of file diff --git a/src/func.c b/src/func.c index a726c69bc3..ab45b1fea9 100644 --- a/src/func.c +++ b/src/func.c @@ -16,9 +16,11 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.1 2002/02/24 01:55:17 drh Exp $ +** $Id: func.c,v 1.2 2002/02/24 17:12:54 drh Exp $ */ #include +#include +#include #include "sqlite.h" /* @@ -45,6 +47,48 @@ static void lowerFunc(void *context, int argc, const char **argv){ } } +/* +** An instance of the following structure holds the context of a +** standard deviation computation. +*/ +typedef struct StdDevCtx StdDevCtx; +struct StdDevCtx { + double sum; /* Sum of terms */ + double sum2; /* Sum of the squares of terms */ + int n; /* Number of terms seen so far */ +}; + +/* +** Routines used to compute the standard deviation as an aggregate. +*/ +static void *stdDevStep(void *stddev, int argc, char **argv){ + StdDevCtx *p; + double x; + if( argc<1 ) return 0; + if( stddev==0 ){ + p = malloc( sizeof(*p) ); + p->n = 0; + p->sum = 0.0; + p->sum2 = 0.0; + }else{ + p = (StdDevCtx*)stddev; + } + x = atof(argv[0]); + p->sum += x; + p->sum2 += x*x; + p->n++; + return p; +} +static void stdDevFinalize(void *stddev, void *context){ + StdDevCtx *p = (StdDevCtx*)stddev; + if( context && p && p->n>1 ){ + double rN = p->n; + sqlite_set_result_double(context, + sqrt((p->sum2 - p->sum*p->sum/rN)/(rN-1.0))); + } + if( stddev ) free(stddev); +} + /* ** This file registered all of the above C functions as SQL ** functions. @@ -52,4 +96,5 @@ static void lowerFunc(void *context, int argc, const char **argv){ void sqliteRegisterBuildinFunctions(sqlite *db){ sqlite_create_function(db, "upper", 1, upperFunc); sqlite_create_function(db, "lower", 1, lowerFunc); + sqlite_create_aggregate(db, "stddev", 1, stdDevStep, stdDevFinalize); }