任何人都可以分享一个例子,我如何为PostgreSQL创建C函数,它将两个整数的数组作为输入并将数组作为输出返回?
对于简单整数我有:
#include "postgres.h"
#include <fmgr.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
int
add_one(int arg) {
arg++;
return arg;
}
在PostgreSQL中编译之后:
load '/usr/lib/postgresql/9.1/lib/add_one';
create or replace function add_one(integer)
returns integer as
'/usr/lib/postgresql/9.1/lib/add_one', 'add_one'
language c;
select add_one(1);
我需要类似的东西:
#include "postgres.h"
#include <fmgr.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
int
add_one(int[] arg) {
arg[1]++;
arg[2] = arg[2] + 2
return arg[];
}
在PostgreSQL中:
load '/usr/lib/postgresql/9.1/lib/add_one';
create or replace function add_one(integer[])
returns integer[] as
'/usr/lib/postgresql/9.1/lib/add_one', 'add_one'
language c;
select add_one(ARRAY[1::int,1::int]);
I have tried从numeric.c修改一些函数,但到目前为止没有任何成功。
答案 0 :(得分:7)
您的代码甚至无法以书面形式远程开始工作。 PostgreSQL不会将Pg级别的数组作为int[]
传递,它会通过PG_FUNCTION_ARGS
(fcinfo
)中的函数上下文传递它们,并且可以通过PG_GETARG_ARRAYTYPE_P
宏访问它们。 / p>
有关基本扩展功能指南,请参阅the docs on C language functions。
查看array_cat
中src/backend/utils/adt/array_userfuncs.c
或array_remove
中src/backend/utils/adt/arrayfuncs.c
的定义。或许多其他选择。
你的骨架看起来像是:
PG_FUNCTION_INFO_V1(add_arrays);
Datum
add_arrays(PG_FUNCTION_ARGS)
{
ArrayType *array1, *array2, *resultarray;
array1 = PG_GETARG_ARRAYTYPE_P(0);
array2 = PG_GETARG_ARRAYTYPE_P(1);
/* Loop over the array bodies and do your mapping to generate resultarray here */
PG_RETURN_ARRAYTYPE_P(resultarray);
}
PostgreSQL C数组API很糟糕,所以我没有时间填写函数体。关键是你的函数签名是错误的 - 你完全误解了它是如何工作的,你写的东西甚至不可能被执行。
然后宣布为:
create or replace function add_arrays(integer[], integer[])
returns integer[] as
'add_arrays', 'add_arrays'
language c immutable strict;
strict
很重要;我提供的函数框架没有检查空输入,所以你需要告诉执行者不要用它们调用它。
如果来自array_map
的{{1}}有一个src/backend/utils/adt/arrayfuncs.c
或map2
变体执行两个数组的锁步迭代,那就太好了。不幸的是它没有,所以你需要自己迭代它们。
重新阅读你的问题后,我现在想知道你是否意味着单个数组的int [] 与两个元素并且你想要整数结果这是数组的总和。如果是这样,请查看zip
模块的工作原理;它简化了处理简单整数数组的功能。