Tom Lane wrote:
> Jan Wieck <[EMAIL PROTECTED]> writes:
> > hlefebvre wrote:
> >> I'd like to return a set of integer in an pl/pgsql function. How can I
> >> do that ?
>
> >     You  can't. Not with PL/pgSQL nor with any other PL or C. The
> >     problem is nested deeper and requires the  planned  querytree
> >     redesign to get solved.
>
> Not really.  Coincidentally enough, I am just in the middle of removing
> execQual.c's hard-wired assumption that only SQL-language functions
> can return sets.  (This is a side effect of fixing the function manager
> so that SQL functions can be called in all contexts, eg used as index
> functions.)  If you want to fix plpgsql so that it retains state and
> can produce multiple elements of a set over repeated calls, the same
> way that SQL functions do, then it could be done today.

    Not   that   easy.  PL/pgSQL  isn't  a  state  machine.   The
    precompiled code is kind of a nested tree of  statements.   A
    RETURN causes a controlled return() through all nested levels
    of the PL executors C calls. This might close  SPI  calls  in
    execution as well. Imagine a code construct like

        FOR rec IN SELECT * FROM customer LOOP
            RETURN rec.cust_id AND RESUME;
        END LOOP;

    which  would  be  the correct syntax for returning sets. What
    happens in PL/pgSQL while execution is, that at the beginning
    of  the  loop the SPI query for SELECT is performed, and then
    the loop executed for all rows in the SPI result set. And  of
    course, you can have nested loops, why not.

    Now  you want to return the first value. If you really return
    to the fmgr at this time, the connection to the  SPI  manager
    must  be  closed,  loosing the result set. So how to continue
    later?

    If we want to make it now for  sets  of  scalar  values  (not
    tuple sets), we could add another feature to the fmgr and the
    PL handlers, which we need later anyway.

    In the case of a call to a PL or C function returning a  set,
    the  fmgr  creates  a temp table and calls the function which
    fills the temp table with all the  return  values.  Now  fmgr
    changes  the  execution  trees  func node in a way that it is
    operating like an SQL function - holding a seqscan  over  the
    temp table. After the last result is returned, the temp table
    is removed. This'd work for tuple sets as well (so  the  temp
    table then is our tuple-source).


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== [EMAIL PROTECTED] #


Reply via email to