I have the following custom type:
我有以下自定义类型:
CREATE TYPE int2_lo_hi AS (
lo int2,
hi int2
);
I want to pass these as an array (int2_lo_hi[]
) to a C function. However, I don't know the correct way to access elements.
我想将这些作为数组传递给一个C函数。但是,我不知道访问元素的正确方式。
Here's my code so far, edited:
以下是我迄今为止编辑过的代码:
Header (no longer used):
头(不再使用):
typedef struct
{
short lo,
hi;
} Int2_lo_hi;
C:
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);
}
The part that is commented out is throwing an error.
注释掉的部分是抛出一个错误。
Note: I'm getting an error that indicates that OID is invalid. Its value is 28642010, which I cannot find any documentation reference to.
注意:我得到的错误表明OID是无效的。它的值是28642010,我找不到任何文档参考。
1 个解决方案
#1
4
After minor fixes this code works:
在小修正之后,这个代码工作:
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);
}
#1
4
After minor fixes this code works:
在小修正之后,这个代码工作:
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);
}