postgresql 如何处理错误:类型数组类型只是一个 shell

rlcwz9us  于 2023-03-01  发布在  PostgreSQL
关注(0)|答案(1)|浏览(226)

在postgresql的用户定义聚合中,我可以返回sql中的数组类型吗?类型arraytype只是一个shell。但是我在返回之前检查了结果,一切似乎都是正确的。
下面是我的SQL,

CREATE FUNCTION res_trans_crimes_c(bytea, bigint)
        RETURNS bytea
        AS 'MODULE_PATHNAME', 'res_trans_crimes_c'
        LANGUAGE C
        IMMUTABLE 
        PARALLEL SAFE;

CREATE FUNCTION finalize_trans_crimes_c(bytea)
        RETURNS ArrayType
        AS 'MODULE_PATHNAME','finalize_trans_crimes_c'
        LANGUAGE C
        IMMUTABLE 
        PARALLEL SAFE;

CREATE AGGREGATE reservoir_sampling_c(bigint)
(
        sfunc = res_trans_crimes_c,
        stype = bytea,
        FINALFUNC = finalize_trans_crimes_c,
        INITCOND='{}'
);

下面是实现finalize_trans_crimes_c返回数组类型的c代码。

PG_FUNCTION_INFO_V1(finalize_trans_crimes_c);
Datum
finalize_trans_crimes_c(PG_FUNCTION_ARGS)
{               

                ArrayType *result;
                Datum *elems;
                int i;
                int num;
                int64 *dr;

                state_c *st = palloc0 (sizeof(state_c));
                bytea  *addr = (bytea *) PG_GETARG_BYTEA_P(0);
                void **new_ptr = (void **) VARDATA(addr);
                st= (state_c *) (*new_ptr);
                num = st->reservoir_size;
                dr = (int64 *) ARR_DATA_PTR(st->reservoir); 
                elems = (Datum *)palloc(num * sizeof(Datum));
                for (i = 0; i < num; i++) {
                        elems[i] = Int64GetDatum(dr[i]); 
                        elog(INFO, "dr[%d] is %ld",i,dr[i]);
                        elog(INFO, "elems[%d] is %ld",i,elems[i]);
                }
                int nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
                result = (ArrayType *) palloc0(nbytes);
                result = construct_array((Datum *)elems, num , INT8OID, sizeof(int64), true, 'i');
                
                PG_RETURN_ARRAYTYPE_P(result);
                //PG_RETURN_ARRAYTYPE_P(st->reservoir); 
}

你能告诉我问题出在哪里吗?

e3bfsja2

e3bfsja21#

存在于C中的数据类型不会自动作为数据类型存在于SQL中。当您尝试使用尚未在SQL中定义的数据类型时,会收到该错误消息。
当你定义一个聚合函数时,SFUNC必须返回STYPE。如果在你的情况下这是一个数组,考虑使用像bigint[]anycompatiblearray这样的数据类型。如果你的状态不能是SQL数据类型,你可以使用internal
有关示例,请参阅PostgreSQL源代码。

相关问题