我有以下自定义类型:
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,我找不到任何文档参考。
答案 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);
}