109 lines
2.2 KiB
C++
109 lines
2.2 KiB
C++
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <mysql/mysql.h>
|
|
|
|
#define NAME "minacum"
|
|
#define N_ARGS 3
|
|
|
|
#define ARG_IVAL 0
|
|
#define ARG_NUM 1
|
|
#define ARG_BASE 2
|
|
|
|
#define INTERVAL(ptr) ((Interval *) ptr)
|
|
#define GET_ARG(n) (args->args[n] == NULL ? 0 : *((long long*) args->args[n]))
|
|
|
|
extern "C" {
|
|
|
|
typedef struct _Interval Interval;
|
|
struct _Interval {
|
|
long long num;
|
|
long long sum;
|
|
Interval* next;
|
|
};
|
|
|
|
void free_data(UDF_INIT *initid) {
|
|
Interval* ival = INTERVAL(initid->ptr);
|
|
Interval* cur;
|
|
while (ival != NULL) {
|
|
cur = ival;
|
|
ival = ival->next;
|
|
free(cur);
|
|
}
|
|
initid->ptr = NULL;
|
|
}
|
|
|
|
long long minacum(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
|
|
Interval* ival = INTERVAL(initid->ptr);
|
|
if (ival == NULL) return 0;
|
|
|
|
long long min;
|
|
long long base = GET_ARG(ARG_BASE);
|
|
|
|
if (ival->num == base) {
|
|
min = ival->sum;
|
|
ival = ival->next;
|
|
} else
|
|
min = 0;
|
|
|
|
long long acum = min;
|
|
|
|
while (ival != NULL) {
|
|
acum += ival->sum;
|
|
if (acum < min) min = acum;
|
|
ival = ival->next;
|
|
}
|
|
|
|
return min;
|
|
}
|
|
|
|
void minacum_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
|
|
long long num = GET_ARG(ARG_IVAL);
|
|
long long amount = GET_ARG(ARG_NUM);
|
|
|
|
Interval* ival = INTERVAL(initid->ptr);
|
|
Interval* prev = ival;
|
|
|
|
while (ival != NULL && ival->num < num) {
|
|
prev = ival;
|
|
ival = ival->next;
|
|
}
|
|
|
|
if (ival == NULL || ival->num > num) {
|
|
Interval* new_ival = INTERVAL(malloc(sizeof(Interval)));
|
|
new_ival->num = num;
|
|
new_ival->sum = amount;
|
|
new_ival->next = ival;
|
|
if (prev != ival)
|
|
prev->next = new_ival;
|
|
else
|
|
initid->ptr = (char *) new_ival;
|
|
} else
|
|
ival->sum += amount;
|
|
}
|
|
|
|
void minacum_clear(UDF_INIT *initid, char *is_null, char *error) {
|
|
free_data(initid);
|
|
}
|
|
|
|
bool minacum_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
|
|
if (args->arg_count == N_ARGS) {
|
|
args->arg_type[ARG_IVAL] = INT_RESULT;
|
|
args->arg_type[ARG_NUM] = INT_RESULT;
|
|
args->arg_type[ARG_BASE] = INT_RESULT;
|
|
initid->maybe_null = 0;
|
|
initid->const_item = 0;
|
|
initid->ptr = NULL;
|
|
return 0;
|
|
} else {
|
|
sprintf(message, "%s must have %d parameters", NAME, N_ARGS);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void minacum_deinit(UDF_INIT *initid) {
|
|
free_data(initid);
|
|
}
|
|
|
|
}
|