0

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

Leo
  • 1
  • 1

1 Answers1

0

I didn't run your code, but that should work in principle. You would use internal as STYPE in CREATE AGGREGATE and as first argument to the state transition function.

You can look at the PostgreSQL source for an example: array_agg uses internal as STYPE, and you can look at the definition of the state transition function array_agg_array_transfn in src/backend/utils/adt/array_userfuncs.c.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263