![]() |
Statistics for MySQL
0.9
|
00001 /* avgw.c (weighted average) */ 00002 00003 /*********************************************************************** 00004 * This code is part of Statistics for MySQL. 00005 * 00006 * Copyright (C) 2011 Heinrich Schuchardt (xypron.glpk@gmx.de) 00007 * 00008 * Licensed under the Apache License, Version 2.0 (the "License"); 00009 * you may not use this file except in compliance with the License. 00010 * You may obtain a copy of the License at 00011 * 00012 * http://www.apache.org/licenses/LICENSE-2.0 00013 * 00014 * Unless required by applicable law or agreed to in writing, software 00015 * distributed under the License is distributed on an "AS IS" BASIS, 00016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00017 * See the License for the specific language governing permissions and 00018 * limitations under the License. 00019 ***********************************************************************/ 00020 00030 #include "sqlstat.h" 00031 00035 struct avgw_storage { 00036 int argc; 00037 double weight; 00038 double sumX; 00039 }; 00040 00053 my_bool avgw_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { 00054 struct avgw_storage * data; 00055 00056 if (args->arg_count < 1 || args->arg_count > 2) { 00057 strcpy(message,"avgw() requires one or two arguments"); 00058 return 1; 00059 } 00060 args->arg_type[0] = REAL_RESULT; 00061 if (args->arg_count > 1) { 00062 args->arg_type[1] = REAL_RESULT; 00063 } 00064 00065 data = (struct avgw_storage *) malloc( sizeof(struct avgw_storage)); 00066 if (data == NULL) { 00067 strcpy(message,"Couldn't allocate memory"); 00068 return 1; 00069 } 00070 data->argc = args->arg_count; 00071 00072 initid->maybe_null = 1; 00073 initid->decimals = NOT_FIXED_DEC; 00074 initid->max_length = 13 + initid->decimals; 00075 initid->ptr = (char *) data; 00076 initid->const_item = 0; 00077 00078 return 0; 00079 } 00080 00092 void avgw_reset(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { 00093 avgw_clear(initid, is_null, error); 00094 avgw_add(initid, args, is_null, error); 00095 } 00096 00106 void avgw_clear(UDF_INIT *initid, char *is_null, char *error) { 00107 struct avgw_storage *data; 00108 data = (struct avgw_storage *) initid->ptr; 00109 data->weight = 0; 00110 data->sumX = 0; 00111 } 00112 00123 void avgw_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { 00124 struct avgw_storage * data; 00125 double x; 00126 double w; 00127 00128 if (!args->args[0]) { 00129 return; 00130 } 00131 data = (struct avgw_storage *) initid->ptr; 00132 if (data->argc > 1) { 00133 if (!args->args[1]) { 00134 return; 00135 } 00136 w = *((double*) args->args[1]); 00137 } else { 00138 w = 1.; 00139 } 00140 x = *((double*) args->args[0]); 00141 00142 data->weight += w; 00143 data->sumX += w * x; 00144 } 00145 00155 double avgw(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { 00156 struct avgw_storage * data; 00157 00158 data = (struct avgw_storage *) initid->ptr; 00159 00160 if (data->weight <= 0) { 00161 *is_null = 1; 00162 return 0; 00163 } 00164 00165 return data->sumX / data->weight; 00166 } 00167 00175 void avgw_deinit(UDF_INIT *initid) { 00176 if (initid->ptr) { 00177 free(initid->ptr); 00178 } 00179 }