Пожалуйста, помогите мне решить проблему возврата встроенного массива. Простой массив для возврата изученного, а затем проблема.
// CREATE TYPE libc_collect_item AS (goods_id bigint, priority integer); -- succsess.
// CREATE TYPE libc_collect AS (collect_number integer, collect_items libc_collect_item[]); -- how to?
//CREATE OR REPLACE FUNCTION f_get_collects() RETURNS SETOF libc_collect_item[] AS 'lib', 'f_get_collects' LANGUAGE C STRICT STABLE;
PG_FUNCTION_INFO_V1(f_get_collects);
Datum
f_get_collects(PG_FUNCTION_ARGS)
{
//....
TupleDesc tupleDesc;
Oid outputTypeId;
get_call_result_type(fcinfo, &outputTypeId, &tupleDesc);
Oid outputBaseTypeId = get_base_element_type(outputTypeId);
Oid outputBaseTypRelId = get_typ_typrelid(outputBaseTypeId);
int16 typlen;
bool typbyval;
char typalign;
get_typlenbyvalalign(outputBaseTypeId, &typlen, &typbyval, &typalign);
const char* attributeNameOne = get_relid_attribute_name(outputBaseTypRelId, 1);
const char* attributeNameTwo = get_relid_attribute_name(outputBaseTypRelId, 2);
Oid attributeOneOid = get_atttype(outputBaseTypRelId, 1);
Oid attributeTwoOid = get_atttype(outputBaseTypRelId, 2);
int32 attributeOneTypMod = get_atttypmod(outputBaseTypRelId, 1);
int32 attributeTwoTypMod = get_atttypmod(outputBaseTypRelId, 2);
TupleDesc my_tupleDesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(my_tupleDesc, 1, attributeNameOne, attributeOneOid, attributeOneTypMod, 0);
TupleDescInitEntry(my_tupleDesc, 2, attributeNameTwo, attributeTwoOid, attributeTwoTypMod, 0);
my_tupleDesc = BlessTupleDesc(my_tupleDesc);
vector<OutCollection> collectionList;
OutCollection item(100002, 1);
collectionList.push_back(item);
OutCollection item2(100003, 2);
collectionList.push_back(item2);
Datum* pResultDatums = (Datum*)palloc(sizeof(Datum) * (int)collectionList.size());
for(int i =0; i < (int)collectionList.size(); i++){
Datum* valueItem = (Datum*) palloc(sizeof(Datum) *2);
valueItem[0] = collectionList[i].orderItemId;
valueItem[1] = collectionList[i].priority;
bool* isNullItem = (bool*) palloc(sizeof(bool) * 2);
isNullItem[0] = false;
isNullItem[1] = false;
HeapTuple resultHeapTupleItem = heap_form_tuple(my_tupleDesc, valueItem, isNullItem);
my_tupleDesc = BlessTupleDesc(my_tupleDesc);
pResultDatums[i] = HeapTupleGetDatum(resultHeapTupleItem);
}
ArrayType* pResult = construct_array(pResultDatums, collectionList.size(), outputBaseTypeId, typlen, typbyval, typalign);
PG_RETURN_ARRAYTYPE_P(pResult);
}
Вероятно, вам нужно как-то создать встроенный массив и вставить его вместо valueItem [1].
Он изучал различные примеры, но ни один из них не подходит.
Мне нужна функция, которая будет возвращать libc_collect []:
//CREATE OR REPLACE FUNCTION f_get_collects() RETURNS SETOF libc_collect[] AS 'lib', 'f_get_collects' LANGUAGE C STRICT STABLE;
=================================
Я стараюсь:
ArrayType* createArray(/*FunctionCallInfo fcinfo, */vector collectionList)
{
Oid outputTypeId;
//Temporary hadrcoded
Oid outputBaseTypeId = 106553;
Oid outputBaseTypRelId = 106551;
int16 typlen;
bool typbyval;
char typalign;
get_typlenbyvalalign(outputBaseTypeId, &typlen, &typbyval, &typalign);
const char* attributeNameOne = "goods_id"; get_relid_attribute_name(outputBaseTypRelId, 1);
const char* attributeNameTwo = "priority"; get_relid_attribute_name(outputBaseTypRelId, 2);
ereport(INFO, (errmsg("Attribute names: %s %s ", attributeNameOne, attributeNameTwo)));
Oid attributeOneOid = 20; get_atttype(outputBaseTypRelId, 1);
Oid attributeTwoOid = 23; get_atttype(outputBaseTypRelId, 2);
int32 attributeOneTypMod = get_atttypmod(outputBaseTypRelId, 1);
int32 attributeTwoTypMod = get_atttypmod(outputBaseTypRelId, 2);
TupleDesc my_tupleDesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(my_tupleDesc, 1, attributeNameOne, attributeOneOid, attributeOneTypMod, 0);
TupleDescInitEntry(my_tupleDesc, 2, attributeNameTwo, attributeTwoOid, attributeTwoTypMod, 0);
my_tupleDesc = BlessTupleDesc(my_tupleDesc);
Datum* pResultDatums = (Datum*)palloc(sizeof(Datum) * (int)collectionList.size());
return pResult;
}
PG_FUNCTION_INFO_V1(f_sys_collects_generate_single_simple2);
Datum
f_sys_collects_generate_single_simple2(PG_FUNCTION_ARGS)
{
vector<OutCollection> collectionList;
OutCollection item(100002, 1);
collectionList.push_back(item);
OutCollection item2(100003, 2);
collectionList.push_back(item2);
TupleDesc tupleDesc;
Oid outputTypeId;
get_call_result_type(fcinfo, &outputTypeId, &tupleDesc);
Oid outputBaseTypeId = get_base_element_type(outputTypeId);
Oid outputBaseTypRelId = get_typ_typrelid(outputBaseTypeId);
int16 typlen;
bool typbyval;
char typalign;
get_typlenbyvalalign(outputBaseTypeId, &typlen, &typbyval, &typalign);
const char* attributeNameOne = get_relid_attribute_name(outputBaseTypRelId, 1);
const char* attributeNameTwo = get_relid_attribute_name(outputBaseTypRelId, 2);
Oid attributeOneOid = get_atttype(outputBaseTypRelId, 1);
Oid attributeTwoOid = get_atttype(outputBaseTypRelId, 2);
int32 attributeOneTypMod = get_atttypmod(outputBaseTypRelId, 1);
int32 attributeTwoTypMod = get_atttypmod(outputBaseTypRelId, 2);
ereport(INFO, (errmsg("Attribute type mods: %i %i ", attributeOneTypMod, attributeTwoTypMod)));
TupleDesc my_tupleDesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(my_tupleDesc, 1, attributeNameOne, attributeOneOid, attributeOneTypMod, 0);
TupleDescInitEntry(my_tupleDesc, 2, attributeNameTwo, attributeTwoOid, attributeTwoTypMod, 0);
my_tupleDesc = BlessTupleDesc(my_tupleDesc);
Datum* pResultDatums = (Datum*)palloc(sizeof(Datum) * (int)collectionList.size());
for(int i =0; i < (int)collectionList.size(); i++){
Datum* valueItem = (Datum*) palloc(sizeof(Datum) *2);
valueItem[0] = i;
ArrayType* pResult2 = createArray(/*fcinfo, */collectionList);
Datum* datums;
Oid elemType = 106553;
int16 elemWidth;
bool elemTypeByVal;
char elemAlignmentCode;
bool* nulls;
int count;
get_typlenbyvalalign(elemType, &elemWidth, &elemTypeByVal, &elemAlignmentCode);
ereport(INFO, (errmsg("elemType: %i", elemType)));
ereport(INFO, (errmsg("elemWidth: %i", elemWidth)));
ereport(INFO, (errmsg("elemTypeByVal: %i", elemTypeByVal)));
deconstruct_array(pResult2, elemType, elemWidth, elemTypeByVal, elemAlignmentCode, &datums, &nulls, &count);
ereport(INFO, (errmsg("count: %i", count)));
valueItem[1] = *datums;
bool* isNullItem = (bool*) palloc(sizeof(bool) * 2);
isNullItem[0] = false;
isNullItem[1] = false;
HeapTuple resultHeapTupleItem = heap_form_tuple(my_tupleDesc, valueItem, isNullItem);
my_tupleDesc = BlessTupleDesc(my_tupleDesc);
pResultDatums[i] = HeapTupleGetDatum(resultHeapTupleItem);
ereport(INFO, (errmsg("outputBaseTypeId: %d", outputBaseTypeId)));
}
ArrayType* pResult = construct_array(pResultDatums, collectionList.size(), outputBaseTypeId, typlen, typbyval, typalign);
PG_RETURN_ARRAYTYPE_P(pResult);
}
И получите ошибку:
.....
Информация: кол-во: 2
Информация: outputBaseTypeId: 106556
ОШИБКА: ошибка поиска в кэше для типа 4294967295