Обсуждение: C function to return tuple
I have these types:
CREATE TYPE p_type AS
(
x double precision,y double precision
);
CREATE TYPE d_type AS
(
i p_type,e p_type,id integer
);
CREATE OR REPLACE FUNCTION d_swap(d_type)
RETURNS d_type
AS '/home/user/PostgreSQL/9.0/lib/mylib','d_swap'
LANGUAGE C STRICT;
My problem is that I don't know how to construct the d_type tuple in the c function. I read the documentation but it only explains how i could do that for a more simple type like p_type.
The difficulty is that d_type has attributes of p_type.
Thank you in advance.
This is the c code I wrote until now:
Datum d_swap(PG_FUNCTION_ARGS) {
HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
HeapTupleHeader i;
HeapTupleHeader e;
bool isnull;
TupleDesc tupdesc;
Datum values[3];
HeapTuple tuple;
int tuplen;
bool *nulls;
i = DatumGetHeapTupleHeader(GetAttributeByName(t, "i", &isnull));
e = DatumGetHeapTupleHeader(GetAttributeByName(t, "e", &isnull));
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("function returning record called in context that cannot accept type record")));
}
BlessTupleDesc(tupdesc);
values[0] = e;
values[1] = i;
values[2] = GetAttributeByName(t, "id", &isnull);
tuplen = tupdesc->natts;
nulls = palloc(tuplen * sizeof (bool));
tuple = heap_form_tuple(tupdesc, values, nulls);
pfree(nulls);
PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
}
Marios Vodas <mvodas@gmail.com> writes: > My problem is that I don't know how to construct the d_type tuple in the c > function. Seems like the main problem with that function is that you're passing an uninitialized "nulls" array to heap_form_tuple. I kinda wonder why you are using a fixed-length values array together with a variable-length, dynamically allocated nulls array, but that' just odd style not wrong in itself. regards, tom lane
I see what you mean and I changed the code BUT still my main problem is that I want to know how to fill values array. I remind you that d_type contains attributes of another composite type p_type.
I need a solution to that because I need to use it in other parts of the code.
Datum d_swap(PG_FUNCTION_ARGS) {
HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
HeapTupleHeader i;
HeapTupleHeader e;
bool isnull;
TupleDesc tupdesc;
Datum values[3];
HeapTuple tuple;
i = DatumGetHeapTupleHeader(GetAttributeByName(t, "i", &isnull));
e = DatumGetHeapTupleHeader(GetAttributeByName(t, "e", &isnull));
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("function returning record called in context that cannot accept type record")));
}
BlessTupleDesc(tupdesc);
//I need to get this working
values[0] = e;
values[1] = i;
values[2] = GetAttributeByName(t, "id", &isnull);
tuple = heap_form_tuple(tupdesc, values, &isnull);
PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
}
On Sun, Sep 26, 2010 at 7:16 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Marios Vodas <mvodas@gmail.com> writes:Seems like the main problem with that function is that you're passing
> My problem is that I don't know how to construct the d_type tuple in the c
> function.
an uninitialized "nulls" array to heap_form_tuple.
I kinda wonder why you are using a fixed-length values array together
with a variable-length, dynamically allocated nulls array, but that'
just odd style not wrong in itself.
regards, tom lane
Marios Vodas <mvodas@gmail.com> writes: > //I need to get this working > *values[0] = e;* > * values[1] = i;* Maybe you're missing HeapTupleGetDatum() there? Just from a data type cleanliness standpoint, you shouldn't ever assign something to Datum or vice versa without applying the correct conversion macro. regards, tom lane
Suppose I had the data that form the returning tuple in 5 variables like this:
float8 xi = 1;
float8 yi = 2;
float8 xe = 3;
float8 ye = 4;
int32 id = 1;
In addition the function wouldn't have any input parameters. It just returns a tuple of type d_type.
Can you tell me how it is possible to form the tuple? My problem here is that I DON'T have HeapTupleHeaders i and e already formed (those two are of p_type) so I have to form them somehow.
On Sun, Sep 26, 2010 at 7:52 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Marios Vodas <mvodas@gmail.com> writes:> //I need to get this working> * values[1] = i;*
> *values[0] = e;*
Maybe you're missing HeapTupleGetDatum() there? Just from a data type
cleanliness standpoint, you shouldn't ever assign something to Datum or
vice versa without applying the correct conversion macro.
regards, tom lane
Do you think it would be better to change d_type to this?
CREATE TYPE d_type AS
(
xi double precision,yi double precision,xe double precision,ye double precision,id integer
);
Note: This is NOT something I want to do but if there is no other way to form d_type tuple from the variables...
On Sun, Sep 26, 2010 at 8:29 PM, Marios Vodas <mvodas@gmail.com> wrote:
Suppose I had the data that form the returning tuple in 5 variables like this:float8 xi = 1;float8 yi = 2;float8 xe = 3;float8 ye = 4;int32 id = 1;In addition the function wouldn't have any input parameters. It just returns a tuple of type d_type.Can you tell me how it is possible to form the tuple? My problem here is that I DON'T have HeapTupleHeaders i and e already formed (those two are of p_type) so I have to form them somehow.