Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL C函数中自定义类型的访问数组_C_Arrays_Postgresql_Function_Postgresql 9.5 - Fatal编程技术网

PostgreSQL C函数中自定义类型的访问数组

PostgreSQL C函数中自定义类型的访问数组,c,arrays,postgresql,function,postgresql-9.5,C,Arrays,Postgresql,Function,Postgresql 9.5,我有以下自定义类型: CREATE TYPE int2_lo_hi AS ( lo int2, hi int2 ); 我想将它们作为数组(int2\u lo\u hi[])传递给C函数。但是,我不知道访问元素的正确方法 以下是我迄今为止编辑的代码: 标题(不再使用): C: PG_功能_信息_V1(阵列测试); PGMODULEEXPORT基准阵列测试(PG函数参数) { ArrayType*a=PG_GETARG_ArrayType_P(0); 如果(ARR_NDIM(a)>1) {

我有以下自定义类型:

CREATE TYPE int2_lo_hi AS (
  lo int2,
  hi int2
);
我想将它们作为数组(
int2\u lo\u hi[]
)传递给C函数。但是,我不知道访问元素的正确方法

以下是我迄今为止编辑的代码:

标题(不再使用):

C:

PG_功能_信息_V1(阵列测试);
PGMODULEEXPORT基准阵列测试(PG函数参数)
{
ArrayType*a=PG_GETARG_ArrayType_P(0);
如果(ARR_NDIM(a)>1)
{
ereport(ERROR,(errcode(errcode_数组_下标_ERROR),errmsg(“需要一维数组”));
}
基准*基准;
布尔*空值;
int elemWidth,count;
Oid elemType=ARR_elemType(a);
bool elemTypeByVal,为空;
字符元素编码;
get_typlenbyvalalign(elemType、&elemWidth、&elemTypeByVal、&elemAlignmentCode);
解构_数组(a、elemType、elemWidth、elemTypeByVal、elemAlignmentCode和基准、空值和计数);
int结果=0;
HEAPTLT;
短*字段;
for(int i=0;i
注释掉的部分抛出错误


注意:我得到一个错误,表明OID无效。它的值是28642010,我找不到任何文档参考。

在进行了一些小的修复后,此代码可以工作:

PG_FUNCTION_INFO_V1(array_test);

Datum
array_test(PG_FUNCTION_ARGS)
{
    ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
    Datum  *datums;
    bool   *nulls;
    int     count;
    int16   elemWidth;
    Oid     elemType = ARR_ELEMTYPE(a);
    bool    elemTypeByVal, isNull;
    char    elemAlignmentCode;
    int     result = 0;
    HeapTupleHeader lt;
    short   field;

    if (ARR_NDIM(a) > 1)
        ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("1-dimensional array needed")));

    get_typlenbyvalalign(elemType, &elemWidth, &elemTypeByVal, &elemAlignmentCode);
    deconstruct_array(a, elemType, elemWidth, elemTypeByVal, elemAlignmentCode, &datums, &nulls, &count);

    for (int i = 0; i < count; i++)
    {
        if (nulls[i])
        {
            result = -result;
        }
        else
        {
            lt = DatumGetHeapTupleHeader(datums[i]);

            field = DatumGetInt16(GetAttributeByNum(lt, 1, &isNull));
            if (!isNull)
                result += field;

            field = DatumGetInt16(GetAttributeByNum(lt, 2, &isNull));
            if (!isNull)
                result += field;
        }
    }

    PG_RETURN_INT32(result);
}
PG_功能_信息_V1(阵列测试);
资料
阵列测试(PG函数参数)
{
ArrayType*a=PG_GETARG_ArrayType_P(0);
基准*基准;
布尔*空值;
整数计数;
int16电子宽度;
Oid elemType=ARR_elemType(a);
bool elemTypeByVal,为空;
字符元素编码;
int结果=0;
HEAPTLT;
短场;
如果(ARR_NDIM(a)>1)
ereport(ERROR,(errcode(errcode_数组_下标_ERROR),errmsg(“需要一维数组”));
get_typlenbyvalalign(elemType、&elemWidth、&elemTypeByVal、&elemAlignmentCode);
解构_数组(a、elemType、elemWidth、elemTypeByVal、elemAlignmentCode和基准、空值和计数);
for(int i=0;i
我认为您需要在
deconstruct\u array
函数中指定确切的数组元素类型,而不是
ANYELEMENTOID
。要确定数组类型,可以使用
AARR\u ELEMTYPE
宏。参见我的同事编写的关于如何使用它的示例(见附件),第四个论点可能是,如果您将元素标记为hanks@IldarMusin,则应为
false
。我将解构行更改为
deconstruct_数组(a,ObjectIdGetDatum(a),4,false,'I',基准,&null,&count)并更改为
Int2_lo_hi*elem=palloc(sizeof(Int2_lo_hi)),但这会产生错误(断开服务器连接)。我在你的建议中遗漏了什么吗?如果不研究代码,很难说。我会尝试用
gdb
进行调试,看看里面发生了什么。如果你在github或其他地方有回购协议,我可以在今天晚些时候研究。我的意思不是
ObjectedAtum
,而是
AARR\u ELEMTYPE
。所以它可能是这样的:
oidtypeid=AARR_ELEMTYPE(a);解构_数组(a,typeid,4,false,'i',基准,&null,&count)PG_FUNCTION_INFO_V1(array_test);

PGMODULEEXPORT Datum array_test(PG_FUNCTION_ARGS)
{
    ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);

    if (ARR_NDIM(a) > 1)
    {
        ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("1-dimensional array needed")));
    }

    Datum *datums;
    bool *nulls;
    int elemWidth, count;
    Oid elemType = ARR_ELEMTYPE(a);
    bool elemTypeByVal, isNull;
    char elemAlignmentCode;
    get_typlenbyvalalign(elemType, &elemWidth, &elemTypeByVal, &elemAlignmentCode);
    deconstruct_array(a, elemType, elemWidth, elemTypeByVal, elemAlignmentCode, &datums, &nulls, &count);
    int result = 0;
    HeapTupleHeader lt;
    short *field;

    for (int i = 0; i < count; i++)
    {
        if (nulls[i])
        {
            result = -result;
        }
        else
        {
            lt = DatumGetHeapTupleHeader(datums[i]);
/*          field = (short*)GetAttributeByNum(lt, 1, &isNull);

            if (!isNull)
            {
                //result += *field;
            }

            field = (short*)GetAttributeByNum(lt, 2, &isNull);

            if (!isNull)
            {
                //result += *field;
            }*/
        }
    }

    PG_RETURN_INT32(result);
}
PG_FUNCTION_INFO_V1(array_test);

Datum
array_test(PG_FUNCTION_ARGS)
{
    ArrayType *a = PG_GETARG_ARRAYTYPE_P(0);
    Datum  *datums;
    bool   *nulls;
    int     count;
    int16   elemWidth;
    Oid     elemType = ARR_ELEMTYPE(a);
    bool    elemTypeByVal, isNull;
    char    elemAlignmentCode;
    int     result = 0;
    HeapTupleHeader lt;
    short   field;

    if (ARR_NDIM(a) > 1)
        ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("1-dimensional array needed")));

    get_typlenbyvalalign(elemType, &elemWidth, &elemTypeByVal, &elemAlignmentCode);
    deconstruct_array(a, elemType, elemWidth, elemTypeByVal, elemAlignmentCode, &datums, &nulls, &count);

    for (int i = 0; i < count; i++)
    {
        if (nulls[i])
        {
            result = -result;
        }
        else
        {
            lt = DatumGetHeapTupleHeader(datums[i]);

            field = DatumGetInt16(GetAttributeByNum(lt, 1, &isNull));
            if (!isNull)
                result += field;

            field = DatumGetInt16(GetAttributeByNum(lt, 2, &isNull));
            if (!isNull)
                result += field;
        }
    }

    PG_RETURN_INT32(result);
}