使用数组输入和数组输出为PostgreSQL创建简单的C函数

时间:2013-12-05 09:47:58

标签: c arrays postgresql input

任何人都可以分享一个例子,我如何为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修改一些函数,但到目前为止没有任何成功。

1 个答案:

答案 0 :(得分:7)

您的代码甚至无法以书面形式远程开始工作。 PostgreSQL不会将Pg级别的数组作为int[]传递,它会通过PG_FUNCTION_ARGSfcinfo)中的函数上下文传递它们,并且可以通过PG_GETARG_ARRAYTYPE_P宏访问它们。 / p>

有关基本扩展功能指南,请参阅the docs on C language functions

查看array_catsrc/backend/utils/adt/array_userfuncs.carray_removesrc/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.cmap2变体执行两个数组的锁步迭代,那就太好了。不幸的是它没有,所以你需要自己迭代它们。

重新阅读你的问题后,我现在想知道你是否意味着单个数组的int [] 两个元素并且你想要整数结果这是数组的总和。如果是这样,请查看zip模块的工作原理;它简化了处理简单整数数组的功能。