Re: Detection of nested function calls

From: Andres Freund <andres(at)2ndquadrant(dot)com>
To: Hugo Mercier <hugo(dot)mercier(at)oslandia(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Detection of nested function calls
Date: 2013-10-28 09:34:00
Message-ID: 20131028093400.GF5577@awork2.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 2013-10-28 10:29:59 +0100, Hugo Mercier wrote:
> Le 28/10/2013 09:39, Andres Freund a écrit :
> > On 2013-10-28 09:13:06 +0100, Hugo Mercier wrote:
> >> Le 25/10/2013 18:44, Tom Lane a écrit :
> >>> Hugo Mercier <hugo(dot)mercier(at)oslandia(dot)com> writes:
> >>>> Le 25/10/2013 17:20, Tom Lane a écrit :
> >>>>> How do you tell the difference between
>
> >>> The point I'm trying to make is that in the first case, foo would be
> >>> receiving a first argument that was flat and a second that was not flat;
> >>> while in the second case, it would be receiving a first argument that was
> >>> not flat and a second that was flat. The expression labeling you're
> >>> proposing does not help it tell the difference.
> >>
> >> No it does not. It's then up to the data type to store whether it is
> >> flat or not. And every functions manipulating this type is assumed to be
> >> aware of this flat/non-flat flagging.
> >
> > But what if the in-memory type contains pointers and is copied or
> > spilled to disk? There needs to be a mechanism handling that case.
>
> It must not happen. The 'nested' boolean may be seen as "everything
> returning from this function may be stored on disk at any time, so
> serialize it" for nested==0.

I don't think that's sufficient. There'll be lots of places where you'd
need to special-case hack this logic.
Think of SELECT aggregate(somefunc(foo)) FROM ... GROUP BY something_else;

> If there is another mechanism to tell, inside a function, if the result
> will be "stored" (stored on disk, copied to another context, ...) or
> not, then I'll be happy with that.

I don't think telling the function that is the right approach at all.

> > I think we'd need another argument to CREATE FUNCTION like SERIALIZE
> > pointing to a function that that has to return data that can be stored
> > on disk. Deserialization would be up to individual functions.
>
> Either as argument to CREATE FUNCTION or to CREATE TYPE, right ?

Err, CREATE TYPE, yes.

> Ok, so a user function calls PG_DETOAST to get its input. The most
> nested will get it straight from where it is stored.
> Then the function can decide to deserialize it in its own format,
> process it, and return it as is, with probably a call to
> PG_RETURN(pointer). Nested function will get their inputs still from
> PG_DETOAST and can use them directly.
> But for the last function in the nesting chain, how the pointer will be
> serialized back to something storeable ? i.e. who will call the
> serialize function declared in CREATE (FUNCTION|TYPE) ?

Something around toast_insert_or_update(). We'd need to set
HeapTupleHasExternal() for those kind of tuples or similar so it gets
called, but that shouldn't be the biggest problem.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Stéphan BEUZE 2013-10-28 09:52:55 Re: ERROR : 'tuple concurrently updated'
Previous Message Hugo Mercier 2013-10-28 09:29:59 Re: Detection of nested function calls