how to return rows of data via function written by language C strict - Mailing list pgsql-general

From Christoph Bilz
Subject how to return rows of data via function written by language C strict
Date
Msg-id F1948E5F-E476-4047-AD2B-ECEA05E40306@icloud.com
Whole thread Raw
Responses Re: how to return rows of data via function written by language Cstrict  (Ian Barwick <ian.barwick@2ndquadrant.com>)
Re: how to return rows of data via function written by language C strict  ("David G. Johnston" <david.g.johnston@gmail.com>)
List pgsql-general
Hello,

i want write functions like this:

CREATE FUNCTION foo(text) returns real as '<path>/foo.dll', 'foo'  LANGUAGE C STRICT;"
CREATE FUNCTION foo2(text) returns table(c1 text, c2 int) as '<path>/foo2.dll', 'foo'  LANGUAGE C STRICT;
So far, so clear. I don't want to return one scalar value or SETOF smth, I want to start the function like this:
select * from foo; … and the rows will be returned.
I read the chapter
https://www.postgresql.org/docs/11/spi.html
and especially 

again and again but I found no solution. So, the functions should return rows of data not just „one“ result or composite types.
The documentation regarding usable examples are very sparse, so I found and tried with this pice of code:

ArrayType* pg_array = DatumGetArrayTypeP(_row_val);
c_array = (float *)ARR_DATA_PTR(pg_array);
pg_array_size = ARR_DIMS(pg_array)[0];
—> so it’s clear  how do I get my data via SPI* functionalty, the result set is within the pg_array or the casted c_array.

I found this within funcapi.h:
 /* Type categories for get_call_result_type and siblings */
typedef enum TypeFuncClass
{   TYPEFUNC_SCALAR,            /* scalar result type */   TYPEFUNC_COMPOSITE,         /* determinable rowtype result */   TYPEFUNC_COMPOSITE_DOMAIN,  /* domain over determinable rowtype result */   TYPEFUNC_RECORD,            /* indeterminate rowtype result */   TYPEFUNC_OTHER              /* bogus type, eg pseudotype */
} TypeFuncClass;

and tried:

TupleDesc   tupdesc;
HeapTuple   tuple;
Datum       rs[100];
int         tuplen;
bool        nulls;

if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_RECORD)   ereport(ERROR,   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),       errmsg("function returning record called in context "           "that cannot accept type record")));

BlessTupleDesc(tupdesc);

for (int j = 0; j < 100; j++) {   rs[j] = Float8GetDatum(c_array[j]);
}

tuplen = tupdesc->natts;
nulls = palloc(tuplen * sizeof(bool));

tuple = heap_form_tuple(tupdesc, rs, nulls);

pfree(nulls);

SPI_finish();

PG_RETURN_DATUM(HeapTupleGetDatum(tuple));


But it doesn’t work. Either the get_call_result_type fails because the function definition doesn’t match or the the client process crashes because smth. happens and I don’t know how this stuff should work.
So, due to the lack of examples in general and the sparse documentation about it, any help will be appreciate.
Thanks.



pgsql-general by date:

Previous
From: John Lumby
Date:
Subject: Re: REINDEX : new parameter to preserve current average leaf densityas new implicit FILLFACTOR
Next
From: Adrian Klaver
Date:
Subject: Re: execute_values