Обсуждение: C-Function: Returning Rows

Поиск
Список
Период
Сортировка

C-Function: Returning Rows

От
Carel Combrink
Дата:
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.



Re: C-Function: Returning Rows

От
Tom Lane
Дата:
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

Re: C-Function: Returning Rows

От
Carel Combrink
Дата:
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.



Re: C-Function: Returning Rows

От
Tom Lane
Дата:
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

Re: C-Function: Returning Rows

От
Carel Combrink
Дата:
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.