#ifdef STANDARD #include #include #ifdef __WIN__ typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */ typedef __int64 longlong; #else typedef unsigned long long ulonglong; typedef long long longlong; #endif /*__WIN__*/ #else #include #include #endif #include #include #include // To get strmov() #ifdef HAVE_DLOPEN /* These must be right or mysqld will not find the symbol! */ extern "C" { my_bool firstval_init( UDF_INIT* initid, UDF_ARGS* args, char* message ); void firstval_deinit( UDF_INIT* initid ); void firstval_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); void firstval_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); double firstval( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); } struct firstval_data { double value; longlong order; int inited; int is_null; }; my_bool firstval_init( UDF_INIT* initid, UDF_ARGS* args, char* message ) { if (args->arg_count != 2) { strcpy(message, "wrong number of arguments: FIRSTVAL() requires 2 arguments"); return 1; } if ((args->arg_type[0] != REAL_RESULT) || (args->arg_type[1] != INT_RESULT) ) { strcpy(message, "wrong argument type: FIRSTVAL() requires a REAL and an INT"); return 1; } initid->maybe_null = 0; initid->decimals = 2; initid->max_length = 20; struct firstval_data* data; data = new struct firstval_data; data->value = 0.0; data->order = 0; data->inited = 0; data->is_null = 1; initid->ptr = (char*)data; return 0; } void firstval_deinit(UDF_INIT* initid) { delete initid->ptr; } void firstval_reset(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message) { struct firstval_data* data = (struct firstval_data*)initid->ptr; data->value = 0.0; data->order = -1; data->inited = 0; data->is_null = 1; *is_null = 0; firstval_add(initid, args, is_null, message); } void firstval_add(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message) { if (args->args[0] && args->args[1]) { struct firstval_data* data = (struct firstval_data*)initid->ptr; double val = *((double*)args->args[0]); longlong ord = *((longlong*)args->args[1]); if (args->args[0] != 0) { if (ord < data->order || data->inited == 0) { data->order = ord; data->inited = 1; data->value = val; } else if (ord == data->order && val < data->value) { data->value = val; } } } else { *is_null = 1; } } double firstval(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error) { struct firstval_data* data = (struct firstval_data*)initid->ptr; if (data->inited != 1) { *is_null = 1; return 0.0; } *is_null = 0; return data->value; } #endif /* HAVE_DLOPEN */