Re: Functions returning complex types.

From: "Thomas Hallgren" <thhal(at)mailblocks(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Functions returning complex types.
Date: 2004-01-26 22:53:09
Message-ID: bv45o8$1bso$1@news.hub.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I found the following piece of code in the plpgsql pl_comp.c module:

/*
* This is a bit ugly --- need a permanent copy of the rel's tupdesc.
* Someday all these mallocs should go away in favor of a per-function
* memory context ...
*/
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
row->rowtupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
MemoryContextSwitchTo(oldcxt);

My guess is that the SQL functions do something similar (pre-compile and
store all TupleDesc's in TopMemoryContext), hence there's no problem with
your example. Writing a C function I get a TupleDesc from the
TypeGetTupleDesc() function that has been allocated using palloc(). I'm
quite sure I don't do anything with memory contexts and the TupleDesc really
seems to go out of scope when the function returns.

If I create a copy of the TupleDesc in the TopMemoryContext directly after
the call to TypeGetTupleDesc, then everything works just fine.

I still suspect that something is broken with the calling mechanism. At
least for languages that do not compile the stuff into permanent structures
prior to evaluating.

Regards,

Thomas Hallgren

"Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote in message
news:14875(dot)1075149255(at)sss(dot)pgh(dot)pa(dot)us(dot)(dot)(dot)
> "Thomas Hallgren" <thhal(at)mailblocks(dot)com> writes:
> > ... exactly the same TupleTableSlot* that is passed into my
> > printMyComplextType function. This is of course extremely bad since the
> > MemoryContext where it was allocated has gone out of scope (I guess,
since
> > this is another call).
>
> I don't think so; unless you are hacking memory contexts internally to
> your function. Here's some empirical proof that the function call
> mechanism is not broken:
>
> regression=# create type mytype as (f1 int ,f2 int);
> CREATE TYPE
> regression=# create function obtaintype(int,int) returns mytype as
> regression-# 'select $1,$2' language sql;
> CREATE FUNCTION
> regression=# select * from obtaintype(1,2);
> f1 | f2
> ----+----
> 1 | 2
> (1 row)
>
> regression=# create function usetype(mytype) returns int as
> regression-# 'select $1.f1 + $1.f2' language sql;
> CREATE FUNCTION
> regression=# select usetype(obtaintype(1,2));
> usetype
> ---------
> 3
> (1 row)
>
> regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
> (send "unregister YourEmailAddressHere" to majordomo(at)postgresql(dot)org)
>

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Christopher Kings-Lynne 2004-01-27 00:25:48 Re: Disaster!
Previous Message Mark Hollow 2004-01-26 22:26:39 Re: Log rotation for pg_autovacuum