postgresql 使用C语言在postgres中创建聚合

nx7onnlm  于 2023-02-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(146)

我想用C语言在postgres中创建用户自定义聚合。下面是我的代码。
sql代码:

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,
);

对于C代码:

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);
}

我可以在转换函数中传递我的结构体指针吗?我想在最终函数中返回ARRAYTYPE。我不知道如何处理它。你能帮助我吗?谢谢!
我想知道如何在postgres中处理c语言中的数组类型和结构

nc1teljy

nc1teljy1#

我没有运行你的代码,但原则上应该可以,你可以使用internal作为CREATE AGGREGATE中的STYPE,并作为状态转换函数的第一个参数。
您可以查看PostgreSQL源代码中的示例:array_agg使用internal作为STYPE,您可以查看src/backend/utils/adt/array_userfuncs.c中状态转换函数array_agg_array_transfn的定义。

相关问题