在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);
}
你能告诉我问题出在哪里吗?
1条答案
按热度按时间e3bfsja21#
存在于C中的数据类型不会自动作为数据类型存在于SQL中。当您尝试使用尚未在SQL中定义的数据类型时,会收到该错误消息。
当你定义一个聚合函数时,
SFUNC
必须返回STYPE
。如果在你的情况下这是一个数组,考虑使用像bigint[]
或anycompatiblearray
这样的数据类型。如果你的状态不能是SQL数据类型,你可以使用internal
。有关示例,请参阅PostgreSQL源代码。