Re: fmgr interface [was: plperl inital pass] - Mailing list pgsql-hackers

From wieck@debis.com (Jan Wieck)
Subject Re: fmgr interface [was: plperl inital pass]
Date
Msg-id m1198O7-0003kvC@orion.SAPserv.Hamburg.dsh.de
Whole thread Raw
In response to fmgr interface [was: plperl inital pass]  ("Mark Hollomon" <mhh@nortelnetworks.com>)
List pgsql-hackers
Mark Hollomon wrote:

> I've been looking at returning a tuple. It looked to me that the
>
> executor would handle a returned tuple okay, it was just SETs that
> would cause problems. But I suspect I am wrong.

    Functions  returning  SET's  allways  return SET's of tuples,
    never SET's of single values. And functions  returning  tuple
    (SET's)  have  a targetlist to specify which attribute of the
    returned tuple(s) is wanted. It is  the  processing  of  this
    funciton-call-targetlist   that's   actually  broken  in  the
    executor.

    But it's not worth fixing it without beeing able after to use
    more  than  one  attribute  of  the  returned  set.  And that
    requires the mentioned subselecting RTE. So  you  could  then
    say things like:

        SELECT X.a, X.c FROM mysetfunc('Mark') X;

    The next problem in returning SET's is, that PostgreSQL isn't
    a state machine - it  is  stack  oriented.  The  way  it  was
    supposed to work with SQL language functions was this:

    1.  The  last  query in an SQL function returning a tuple SET
        is allways a SELECT.

    2.  When the FUNC node is first  hit  during  execution,  the
        function  is  called.   Then the FUNC node is modified by
        the executor and references the  execution  tree  of  the
        last command in the function.

    3.  Subsequent  function  calls  don't  invoke  the  function
        again, instead functions last commands execution tree  is
        asked for the next tuple.

    This  mechanism  could  also  work  for  PL  functions.  A PL
    function returning a  SET  creates  a  temp  table.  At  each
    occurence of

        RETURN mytup AND RESUME;

    it  adds  the  tuple  to the temp table. If it finally really
    returns, it hands back an execution plan for a

        SELECT * FROM <my_invocations_temp_table>;

    Then again, the problem of using multiple attributes  of  the
    returned set remains.


> The best I could come up with for creating the tuple was using
>
> heap_formtuple. But that requires a TupleDesc so I was going to
>
> use heap_openr. But that needs the name of the relation which is
>
> avaible from the Form_pg_data (?) structure for the return type,
>
> which we already must get.

    Of   course,   the   PL   function  must  create  tuples  via
    heap_formtuple().  Thus, we need a pg_class entry (etc.)  for
    it. The PL handler knows the return type of the function it's
    handling from pg_proc. The corresponding pg_type entry has  a
    non-zero  typrelid indicating that it's a tuple type.  Simply
    use heap_open() with that typrelid and you'll get it.

    I'd like to add a new type of relation when we go for  return
    SET's.

        CREATE STRUCTURE structname (attname type [, ...]);

    It  just  causes  another pg_class entry, but these relations
    aren't  accessible  by  normal  means  and  do  not  have  an
    underlying  file.  Don't  know  if it's valid SQL syntax, but
    what else could tell the parser what type of a  tuple  a  SET
    function  will  return  if  it's  not  an  existing  relation
    structure?


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#========================================= wieck@debis.com (Jan Wieck) #

pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: [HACKERS] More on shared objects problem
Next
From: Tom Lane
Date:
Subject: Re: [HACKERS] UPDATE performance degradation (6.5.1)