在PostgreSQL C函数

时间:2016-09-01 07:55:34

标签: c arrays postgresql function postgresql-9.5

我有以下自定义类型:

CREATE TYPE int2_lo_hi AS (
  lo int2,
  hi int2
);

我想将这些作为数组(int2_lo_hi[])传递给C函数。但是,我不知道访问元素的正确方法。

到目前为止,这是我的代码,编辑:

标题(不再使用):

typedef struct
{
    short   lo,
            hi;
} Int2_lo_hi;

C:

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);
}

被注释掉的部分正在抛出错误。

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

1 个答案:

答案 0 :(得分:4)

经过小修复后,此代码可以正常运行:

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);
}