Thread: C-Function: Returning Rows
hi, I have a C Function that returns a row. The following was used to create the function (some code omitted): CREATE TYPE __Result AS (status integer, last_response integer); CREATE OR REPLACE FUNCTION my_function(...) RETURNS __Result ... in my function I have the following: TupleDesc tup_descriptor; Datum dat_values[2]; HeapTuple heap_tuple; bool *pNulls; get_call_result_type(fcinfo, NULL, &tup_descriptor); BlessTupleDesc(tup_descriptor); dat_values[0] = Int32GetDatum(50); dat_values[1] = Int32GetDatum(20); iTup_Length = tup_descriptor->natts; pNulls = palloc(iTup_Length * sizeof(bool)); heap_tuple = heap_form_tuple(tup_descriptor, dat_values, pNulls); PG_RETURN_DATUM(HeapTupleGetDatum(heap_tuple)); Calling the function works as expected but the return values (row) is not correct, there is some problems. Sometimes when I call the function I get: my_function -------------- (50,20) (1 row) and other times I get: my_function -------------- (,) (1 row) and I have seen: my_function -------------- (50,) (1 row) Am I doing something wrong in my function that would have this affect? I do not want to return the hard coded values but rather variables in my function, this is for testing. PostgreSQL 8.4 on Ubuntu 10.04 -- Carel Combrink s25291930@tuks.co.za This message and attachments are subject to a disclaimer. Please refer to www.it.up.ac.za/documentation/governance/disclaimer/ for full details. / Hierdie boodskap en aanhangsels is aan 'n vrywaringsklousule onderhewig. Volledige besonderhede is by www.it.up.ac.za/documentation/governance/disclaimer/ beskikbaar.
Carel Combrink <s25291930@tuks.co.za> writes: > in my function I have the following: > TupleDesc tup_descriptor; > Datum dat_values[2]; > HeapTuple heap_tuple; > bool *pNulls; > get_call_result_type(fcinfo, NULL, &tup_descriptor); > BlessTupleDesc(tup_descriptor); > dat_values[0] = Int32GetDatum(50); > dat_values[1] = Int32GetDatum(20); > iTup_Length = tup_descriptor->natts; > pNulls = palloc(iTup_Length * sizeof(bool)); > heap_tuple = heap_form_tuple(tup_descriptor, dat_values, pNulls); > PG_RETURN_DATUM(HeapTupleGetDatum(heap_tuple)); > Am I doing something wrong in my function that would have this affect? Failing to initialize the values of pNulls[], no doubt. It would also be a good idea to check for a failure result from get_call_result_type. BTW, what's the rationale for using a fixed-length Datum array and a variable-length nulls array? Usually people handle both of those the same way. regards, tom lane
Quoting Tom Lane <tgl@sss.pgh.pa.us>: > Carel Combrink <s25291930@tuks.co.za> writes: >> in my function I have the following: >> TupleDesc tup_descriptor; >> Datum dat_values[2]; >> HeapTuple heap_tuple; >> bool *pNulls; > >> get_call_result_type(fcinfo, NULL, &tup_descriptor); >> BlessTupleDesc(tup_descriptor); >> dat_values[0] = Int32GetDatum(50); >> dat_values[1] = Int32GetDatum(20); >> iTup_Length = tup_descriptor->natts; >> pNulls = palloc(iTup_Length * sizeof(bool)); >> heap_tuple = heap_form_tuple(tup_descriptor, dat_values, pNulls); >> PG_RETURN_DATUM(HeapTupleGetDatum(heap_tuple)); > >> Am I doing something wrong in my function that would have this affect? > > Failing to initialize the values of pNulls[], no doubt. > > It would also be a good idea to check for a failure result from > get_call_result_type. > > BTW, what's the rationale for using a fixed-length Datum array and > a variable-length nulls array? Usually people handle both of those > the same way. > > regards, tom lane > I've added a line to initialize the values like follow: malloc(pNulls, false, iTup_Length * sizeof(bool)); and it works perfectly each time. As for checking the failure result: I did not put it in my email but actually I am checking to see if it is not "TYPEFUNC_COMPOSITE". I did use a fixed-length nulls array but somewhere in my testing/frustration I mixed the two (I played with various options). I noted, if using fixed-length nulls array I should set the array to false also otherwise the same is experienced. Is this supposed to happen this way? Is there documentation on this, I tried googling the function with no success? Thank you Tom, -- Carel Combrink s25291930@tuks.co.za This message and attachments are subject to a disclaimer. Please refer to www.it.up.ac.za/documentation/governance/disclaimer/ for full details. / Hierdie boodskap en aanhangsels is aan 'n vrywaringsklousule onderhewig. Volledige besonderhede is by www.it.up.ac.za/documentation/governance/disclaimer/ beskikbaar.
Carel Combrink <s25291930@tuks.co.za> writes: > I've added a line to initialize the values like follow: > malloc(pNulls, false, iTup_Length * sizeof(bool)); > and it works perfectly each time. malloc? malloc doesn't guarantee to deliver pre-zeroed storage, though it might happen to look like that if you don't test very thoroughly. You've likely also got a problem with leaking the storage, unless you remember to free it explicitly. Personally I'd have used palloc0. > I noted, if using fixed-length nulls array I should set the array to > false also otherwise the same is experienced. Is this supposed to > happen this way? Is there documentation on this, I tried googling the > function with no success? As a general rule, passing an uninitialized input parameter to a function isn't a good thing ;-). I can't say how helpful google might be, but there are certainly plenty of examples of using heap_form_tuple in the PG source code. regards, tom lane
Quoting Tom Lane <tgl@sss.pgh.pa.us>: > Carel Combrink <s25291930@tuks.co.za> writes: >> I've added a line to initialize the values like follow: >> malloc(pNulls, false, iTup_Length * sizeof(bool)); >> and it works perfectly each time. > > malloc? malloc doesn't guarantee to deliver pre-zeroed storage, though > it might happen to look like that if you don't test very thoroughly. > You've likely also got a problem with leaking the storage, unless you > remember to free it explicitly. Personally I'd have used palloc0. > Sorry I'm sleep deprived :P Used memset NOT malloc... If you look at the arguments you'll see I'm using memset not malloc since malloc only takes the size as argument. Sorry but thanks for the valued help >> I noted, if using fixed-length nulls array I should set the array to >> false also otherwise the same is experienced. Is this supposed to >> happen this way? Is there documentation on this, I tried googling the >> function with no success? > > As a general rule, passing an uninitialized input parameter to a > function isn't a good thing ;-). I can't say how helpful google > might be, but there are certainly plenty of examples of using > heap_form_tuple in the PG source code. > > regards, tom lane > -- Carel Combrink s25291930@tuks.co.za This message and attachments are subject to a disclaimer. Please refer to www.it.up.ac.za/documentation/governance/disclaimer/ for full details. / Hierdie boodskap en aanhangsels is aan 'n vrywaringsklousule onderhewig. Volledige besonderhede is by www.it.up.ac.za/documentation/governance/disclaimer/ beskikbaar.