From: | Christoph Bilz <christoph(dot)bilz(at)icloud(dot)com> |
---|---|
To: | pgsql-general(at)lists(dot)postgresql(dot)org |
Subject: | how to return rows of data via function written by language C strict |
Date: | 2019-07-09 20:00:06 |
Message-ID: | F1948E5F-E476-4047-AD2B-ECEA05E40306@icloud.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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 <https://www.postgresql.org/docs/11/spi.html>
and especially
https://www.postgresql.org/docs/11/xfunc-c.html#id-1.8.3.13.11 <https://www.postgresql.org/docs/11/xfunc-c.html#id-1.8.3.13.11>
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.
From | Date | Subject | |
---|---|---|---|
Next Message | Adrian Klaver | 2019-07-09 20:25:03 | Re: execute_values |
Previous Message | John Lumby | 2019-07-09 19:29:37 | Re: REINDEX : new parameter to preserve current average leaf density as new implicit FILLFACTOR |