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

Tom*_*eif 1 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;
}
Run Code Online (Sandbox Code Playgroud)

在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);
Run Code Online (Sandbox Code Playgroud)

我需要这样的东西:

#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[];
}
Run Code Online (Sandbox Code Playgroud)

在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]);
Run Code Online (Sandbox Code Playgroud)

我试图从numeric.c修改一些函数,但到目前为止没有任何成功.

Cra*_*ger 7

您的代码甚至不会以书面形式远程开始工作.PostgreSQL不传递Pg级数组int[],因为它通过PG_FUNCTION_ARGS(fcinfo)中的函数上下文传递它们,并且它们是通过PG_GETARG_ARRAYTYPE_P宏访问的.

有关基本扩展功能指南,请参阅有关C语言函数的文档.

看一下array_catin src/backend/utils/adt/array_userfuncs.carray_removein 的定义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);
}
Run Code Online (Sandbox Code Playgroud)

PostgreSQL C数组API很糟糕,所以我没有时间填写函数体.关键是你的函数签名是错误的 - 你完全误解了它是如何工作的,你写的东西甚至不可能被执行.

然后将其声明为:

create or replace function add_arrays(integer[], integer[])
returns integer[] as
'add_arrays', 'add_arrays'
language c immutable strict;
Run Code Online (Sandbox Code Playgroud)

strict很重要; 我提供的函数框架不检查空输入,因此您需要告诉执行程序不要使用它们来调用它.

这会是很好,如果array_mapsrc/backend/utils/adt/arrayfuncs.c有一个map2zip变体做了两阵的锁步迭代.不幸的是它没有,所以你需要自己迭代它们.

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