I want to create user-defined aggregate in postgres by C language. Here are my code.
sql code:
CREATE FUNCTION res_tras_crimes_c(state_c, int64)
RETURNS state_c
AS 'MODULE_PATHNAME', 'res_tras_crimes'
LANGUAGE C
IMMUTABLE
PARALLEL SAFE;
CREATE FUNCTION finalize_trans_crimes_c(state_c)
RETURNS ArrayType
AS 'MODULE_PATHNAME'
LANGUAGE C
IMMUTABLE
PARALLEL SAFE;
CREATE AGGREGATE reservoir_sampling_c(int64)
(
sfunc = res_tras_crimes,
stype = state_c,
FINALFUNC = finalize_trans_crimes,
);
For C code:
typedef struct state_c
{
int64 *reservoir;
int32 poscnt;
int32 reservoir_size;
} state_c;
PG_FUNCTION_INFO_V1(res_tras);
Datum
res_tras(PG_FUNCTION_ARGS)
{
//state_c *d1 = malloc(sizeof(state_c));
//struct state_c st;
// st = (state_c *)PG_GETARG_DATUM(0);
struct state_c *st = (state_c *)PG_GETARG_POINTER(0);
int64 newsample = PG_GETARG_INT64(1);
if(st == NULL) {
int64 r[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int64 *a = r;
st->poscnt = 1;
st->reservoir_size = 100;
st->reservoir = a;
}
if(st->poscnt <= st->reservoir_size){
int32 p = st->poscnt;
*(st->reservoir+p-1) = newsample;
st->poscnt ++;
}else{
int32 pos = rand() % st->poscnt ; //0 - postcnt -1
if(pos < st->reservoir_size){
*(st->reservoir+pos) = newsample;
}
st->poscnt ++;
}
PG_RETURN_POINTER(st);
}
PG_FUNCTION_INFO_V1(finalize_trans);
Datum
finalize_trans_(PG_FUNCTION_ARGS)
{
struct state_c *st = (state_c *) PG_GETARG_POINTER(0);
PG_RETURN_ARRAYTYPE_P(st->reservoir);
}
Can i pass my struct pointer in transition function? and I want to return ARRAYTYPE in final function. I don't konw how to deal with it. Colud you help me? Thanks!
I want to know how to deal the arraytype and struct in c language in postgres