Обсуждение: C Function returning a tuple with a float4 array as column
HI, Anyone have any ideas what wrong with my C code to return a tuple with 1 column that is a float4 array. I have tested functions returning a float4 array and a row and both work independently. When I combine the code I get the SQL error ERROR: cache lookup failed for type 0 ********** Error ********** ERROR: cache lookup failed for type 0 SQL state: XX000 from the SQL query select pg_backend_pid(), getrecordarray(); The function is defined create or replace function GetRecordArray() returns table ( Param_1 real[] ) AS ..... LANGUAGE C STRICT; The C code is PG_FUNCTION_INFO_V1(GetRecordAray); /** GetRecordArray Function to return a record with 1 column as a Float4 array @returns record with a float4 array **/ DLLEXPORT Datum GetRecordArray(PG_FUNCTION_ARGS) { Datum column[1]; /* Columns for the record */ bool isNULL[1] = { false }; Datum results; /* Results tuple */ HeapTuple tuple; /* Record Tuple */ TupleDesc tupleDesc; /* Tuple descripton */ float dataArray[2] = { 1.1f, 3.1e-16f }; ArrayType * arrayType; Datum *datum; int16 typlen; bool typbyval; char typalign; datum = (Datum *)palloc(sizeof(Datum) * 2); datum[0] = Float4GetDatum(dataArray[0]); datum[1] = Float4GetDatum(dataArray[1]); get_typlenbyvalalign(FLOAT4OID, &typlen, &typbyval, &typalign); arrayType = construct_array(datum, 2, FLOAT4OID, typlen, typbyval, typalign); /* Create and bless the template */ tupleDesc = CreateTemplateTupleDesc(1, false); TupleDescInitEntry(tupleDesc, (AttrNumber) 1, "Param_1", FLOAT4ARRAYOID, -1, 0); tupleDesc = BlessTupleDesc(tupleDesc); /** Set up the column Datum for the Tuple **/ column[0] = DatumGetPointer(arrayType); /** Build the tuple **/ tuple = heap_form_tuple(tupleDesc, column, isNULL); results = HeapTupleGetDatum(tuple); PG_RETURN_DATUM(results); }
Tim <tim.child@comcast.net> writes: > Anyone have any ideas what wrong with my C code to return a tuple with > 1 column that is a float4 array. I have tested functions returning a > float4 array and a row and both work independently. When I combine the > code I get the SQL error > ERROR: cache lookup failed for type 0 I don't think that has anything directly to do with the float4 array. You'd be well ahead of the game if you cranked up gdb to see exactly where the error is coming from (set a breakpoint at errfinish and backtrace from there). But what seems likely to be the problem is that you've declared the function to return set (that's implied by the RETURNS TABLE syntax) but not coded it to do any such thing. I'm guessing some piece of code is confused by the function's failure to follow the SRF API. FWIW, this is backwards: > /** Set up the column Datum for the Tuple **/ > column[0] = DatumGetPointer(arrayType); Should be PointerGetDatum. Now generally both of those are no-op casts, so the difference is cosmetic. It does however suggest that you are either compiling without warnings or ignoring the warnings, neither of which is a path to success in dealing with C code. regards, tom lane
I wrote: > ... But what seems likely to be the problem is that > you've declared the function to return set (that's implied by the > RETURNS TABLE syntax) but not coded it to do any such thing. I'm > guessing some piece of code is confused by the function's failure to > follow the SRF API. No, scratch that: the problem is with that syntax, but in the columns direction not the rows direction. Since you've only got one column, the TABLE syntax degenerates to one OUT param, which is treated as though it were just the normal function result. IOW, this function shouldn't be returning a tuple at all, but just the array datum. regards, tom lane
Tom, Thanks for the feedback. To clarify, don't need to return multiple rows, just a single row which is a composite type that contains multiple arrays. My apologies for using the incorrect terminology. I have successfully written individual functions to return arrays and to return composites. The function to return a composite type used the SRF functions with a row count of 1. So re-phrasing my question what would the code sequence look like to return a single composite type, that contained 1 or more arrays? regards Tim On 12/5/2010 1:03 PM, Tom Lane wrote: > I wrote: >> ... But what seems likely to be the problem is that >> you've declared the function to return set (that's implied by the >> RETURNS TABLE syntax) but not coded it to do any such thing. I'm >> guessing some piece of code is confused by the function's failure to >> follow the SRF API. > No, scratch that: the problem is with that syntax, but in the columns > direction not the rows direction. Since you've only got one column, > the TABLE syntax degenerates to one OUT param, which is treated as > though it were just the normal function result. IOW, this function > shouldn't be returning a tuple at all, but just the array datum. > > regards, tom lane >
Tim <tim.child@comcast.net> writes: > So re-phrasing my question what would the code sequence look like > to return a single composite type, that contained 1 or more arrays? If that's where you want to go, then just go there. The single-column-result case is different from the multi-column-result case, and I think your code is already correct for the latter (barring the PointerGetDatum issue). regards, tom lane
Tom thanks Problem the was resolved with the PointerGetDatum correction. Regards Tim On 12/6/2010 7:33 AM, Tom Lane wrote: > Tim<tim.child@comcast.net> writes: >> So re-phrasing my question what would the code sequence look like >> to return a single composite type, that contained 1 or more arrays? > If that's where you want to go, then just go there. The > single-column-result case is different from the multi-column-result > case, and I think your code is already correct for the latter (barring > the PointerGetDatum issue). > > regards, tom lane >