1dc04c583Sdrh /* 2dc04c583Sdrh ** 2002 February 23 3dc04c583Sdrh ** 4dc04c583Sdrh ** The author disclaims copyright to this source code. In place of 5dc04c583Sdrh ** a legal notice, here is a blessing: 6dc04c583Sdrh ** 7dc04c583Sdrh ** May you do good and not evil. 8dc04c583Sdrh ** May you find forgiveness for yourself and forgive others. 9dc04c583Sdrh ** May you share freely, never taking more than you give. 10dc04c583Sdrh ** 11dc04c583Sdrh ************************************************************************* 12dc04c583Sdrh ** This file contains the C functions that implement various SQL 13dc04c583Sdrh ** functions of SQLite. 14dc04c583Sdrh ** 15dc04c583Sdrh ** There is only one exported symbol in this file - the function 16dc04c583Sdrh ** sqliteRegisterBuildinFunctions() found at the bottom of the file. 17dc04c583Sdrh ** All other code has file scope. 18dc04c583Sdrh ** 19*a2ed5601Sdrh ** $Id: func.c,v 1.3 2002/02/26 23:55:31 drh Exp $ 20dc04c583Sdrh */ 21dc04c583Sdrh #include <ctype.h> 22d3a149efSdrh #include <math.h> 23d3a149efSdrh #include <stdlib.h> 24dc04c583Sdrh #include "sqlite.h" 25dc04c583Sdrh 26dc04c583Sdrh /* 27dc04c583Sdrh ** Implementation of the upper() and lower() SQL functions. 28dc04c583Sdrh */ 29dc04c583Sdrh static void upperFunc(void *context, int argc, const char **argv){ 30dc04c583Sdrh char *z; 31dc04c583Sdrh int i; 32dc04c583Sdrh if( argc<1 || argv[0]==0 ) return; 33dc04c583Sdrh z = sqlite_set_result_string(context, argv[0], -1); 34dc04c583Sdrh if( z==0 ) return; 35dc04c583Sdrh for(i=0; z[i]; i++){ 36dc04c583Sdrh if( islower(z[i]) ) z[i] = toupper(z[i]); 37dc04c583Sdrh } 38dc04c583Sdrh } 39dc04c583Sdrh static void lowerFunc(void *context, int argc, const char **argv){ 40dc04c583Sdrh char *z; 41dc04c583Sdrh int i; 42dc04c583Sdrh if( argc<1 || argv[0]==0 ) return; 43dc04c583Sdrh z = sqlite_set_result_string(context, argv[0], -1); 44dc04c583Sdrh if( z==0 ) return; 45dc04c583Sdrh for(i=0; z[i]; i++){ 46dc04c583Sdrh if( isupper(z[i]) ) z[i] = tolower(z[i]); 47dc04c583Sdrh } 48dc04c583Sdrh } 49dc04c583Sdrh 50dc04c583Sdrh /* 51d3a149efSdrh ** An instance of the following structure holds the context of a 52*a2ed5601Sdrh ** variance or standard deviation computation. 53d3a149efSdrh */ 54d3a149efSdrh typedef struct StdDevCtx StdDevCtx; 55d3a149efSdrh struct StdDevCtx { 56d3a149efSdrh double sum; /* Sum of terms */ 57d3a149efSdrh double sum2; /* Sum of the squares of terms */ 58d3a149efSdrh int n; /* Number of terms seen so far */ 59d3a149efSdrh }; 60d3a149efSdrh 61d3a149efSdrh /* 62d3a149efSdrh ** Routines used to compute the standard deviation as an aggregate. 63d3a149efSdrh */ 64d3a149efSdrh static void *stdDevStep(void *stddev, int argc, char **argv){ 65d3a149efSdrh StdDevCtx *p; 66d3a149efSdrh double x; 67d3a149efSdrh if( argc<1 ) return 0; 68d3a149efSdrh if( stddev==0 ){ 69d3a149efSdrh p = malloc( sizeof(*p) ); 70d3a149efSdrh p->n = 0; 71d3a149efSdrh p->sum = 0.0; 72d3a149efSdrh p->sum2 = 0.0; 73d3a149efSdrh }else{ 74d3a149efSdrh p = (StdDevCtx*)stddev; 75d3a149efSdrh } 76d3a149efSdrh x = atof(argv[0]); 77d3a149efSdrh p->sum += x; 78d3a149efSdrh p->sum2 += x*x; 79d3a149efSdrh p->n++; 80d3a149efSdrh return p; 81d3a149efSdrh } 82d3a149efSdrh static void stdDevFinalize(void *stddev, void *context){ 83d3a149efSdrh StdDevCtx *p = (StdDevCtx*)stddev; 84d3a149efSdrh if( context && p && p->n>1 ){ 85d3a149efSdrh double rN = p->n; 86d3a149efSdrh sqlite_set_result_double(context, 87d3a149efSdrh sqrt((p->sum2 - p->sum*p->sum/rN)/(rN-1.0))); 88d3a149efSdrh } 89d3a149efSdrh if( stddev ) free(stddev); 90d3a149efSdrh } 91d3a149efSdrh 92d3a149efSdrh /* 93*a2ed5601Sdrh ** This function registered all of the above C functions as SQL 94*a2ed5601Sdrh ** functions. This should be the only routine in this file with 95*a2ed5601Sdrh ** external linkage. 96dc04c583Sdrh */ 97dc04c583Sdrh void sqliteRegisterBuildinFunctions(sqlite *db){ 98dc04c583Sdrh sqlite_create_function(db, "upper", 1, upperFunc); 99dc04c583Sdrh sqlite_create_function(db, "lower", 1, lowerFunc); 100d3a149efSdrh sqlite_create_aggregate(db, "stddev", 1, stdDevStep, stdDevFinalize); 101dc04c583Sdrh } 102