【问题标题】:Create simple C function for PostgreSQL with array input and array output使用数组输入和数组输出为 PostgreSQL 创建简单的 C 函数
【发布时间】:2013-12-05 09:47:57
【问题描述】:

谁能分享我如何为 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 中的某些函数,但到目前为止没有任何成功。

【问题讨论】:

    标签: c arrays postgresql input


    【解决方案1】:

    您的代码甚至无法远程开始按所编写的那样工作。 PostgreSQL 不会将 Pg 级别的数组作为 int[] 传递,而是通过 PG_FUNCTION_ARGS (fcinfo) 中的函数上下文传递它们,并通过 PG_GETARG_ARRAYTYPE_P 宏访问它们。

    基本扩展功能指导见the docs on C language functions

    看看array_catsrc/backend/utils/adt/array_userfuncs.c中的定义,或者array_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 很重要;我提供的函数骨架不检查空输入,所以你需要告诉执行器不要用它们调用它。

    如果src/backend/utils/adt/arrayfuncs.c 中的array_map 有一个map2zip 变体来执行两个数组的锁步迭代,那就太好了。不幸的是它没有,所以你需要自己迭代它们。

    重新阅读您的问题后,我现在想知道您的意思是 单个 int[] 数组与 两个元素 并且您想要 integer 结果 那是数组的总和。如果是这样,看看intarray 模块是如何工作的;它具有处理简单整数数组的简化函数。

    【讨论】:

    • 谢谢,您的回答真的很有帮助。我想将一个包含 2 个元素(两个整数)的数组传递给 C 函数,并返回一个包含 2 个整数的数组。
    • @TomasGreif ... 整数会怎样?它对整数做什么?你想给它们添加一个常量吗?在这种情况下,您可以使用 array_map 函数来生成结果。
    • 向第一个元素添加 1,向第二个元素添加 2,并以相同的顺序返回元素。对于 [1,2],我希望结果是 [2,4]。
    • @TomasGreif 好的,因此您需要循环输入数组元素并在构造结果数组后将值分配给结果数组。浏览内置数组函数和intarray 中的函数,您会看到一些有用的示例。
    猜你喜欢
    • 1970-01-01
    • 2017-11-01
    • 2012-12-29
    • 2021-12-12
    • 2017-07-11
    • 2015-08-29
    • 1970-01-01
    • 2021-03-13
    • 2018-12-01
    相关资源
    最近更新 更多