mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
PL/pgSQL functions can return sets. Neil Conway's patch, modified so
that the functionality is available to anyone via ReturnSetInfo, rather than hard-wiring it to PL/pgSQL.
This commit is contained in:
@@ -371,36 +371,61 @@ tuple toaster will decide whether toasting is needed.
|
||||
Functions accepting or returning sets
|
||||
-------------------------------------
|
||||
|
||||
As of 7.1, Postgres has limited support for functions returning sets;
|
||||
this is presently handled only in SELECT output expressions, and the
|
||||
behavior is to generate a separate output tuple for each set element.
|
||||
There is no direct support for functions accepting sets; instead, the
|
||||
function will be called multiple times, once for each element of the
|
||||
input set. This behavior will very likely be changed in future releases,
|
||||
but here is how it works now:
|
||||
[ this section revised 29-Aug-2002 for 7.3 ]
|
||||
|
||||
If a function is marked in pg_proc as returning a set, then it is called
|
||||
with fcinfo->resultinfo pointing to a node of type ReturnSetInfo. A
|
||||
function that desires to return a set should raise an error "called in
|
||||
context that does not accept a set result" if resultinfo is NULL or does
|
||||
not point to a ReturnSetInfo node. ReturnSetInfo contains a field
|
||||
not point to a ReturnSetInfo node.
|
||||
|
||||
There are currently two modes in which a function can return a set result:
|
||||
value-per-call, or materialize. In value-per-call mode, the function returns
|
||||
one value each time it is called, and finally reports "done" when it has no
|
||||
more values to return. In materialize mode, the function's output set is
|
||||
instantiated in a Tuplestore object; all the values are returned in one call.
|
||||
Additional modes might be added in future.
|
||||
|
||||
ReturnSetInfo contains a field "allowedModes" which is set (by the caller)
|
||||
to a bitmask that's the OR of the modes the caller can support. The actual
|
||||
mode used by the function is returned in another field "returnMode". For
|
||||
backwards-compatibility reasons, returnMode is initialized to value-per-call
|
||||
and need only be changed if the function wants to use a different mode.
|
||||
The function should elog() if it cannot use any of the modes the caller is
|
||||
willing to support.
|
||||
|
||||
Value-per-call mode works like this: ReturnSetInfo contains a field
|
||||
"isDone", which should be set to one of these values:
|
||||
|
||||
ExprSingleResult /* expression does not return a set */
|
||||
ExprMultipleResult /* this result is an element of a set */
|
||||
ExprEndResult /* there are no more elements in the set */
|
||||
|
||||
A function returning set returns one set element per call, setting
|
||||
fcinfo->resultinfo->isDone to ExprMultipleResult for each element.
|
||||
After all elements have been returned, the next call should set
|
||||
isDone to ExprEndResult and return a null result. (Note it is possible
|
||||
to return an empty set by doing this on the first call.)
|
||||
(the caller will initialize it to ExprSingleResult). If the function simply
|
||||
returns a Datum without touching ReturnSetInfo, then the call is over and a
|
||||
single-item set has been returned. To return a set, the function must set
|
||||
isDone to ExprMultipleResult for each set element. After all elements have
|
||||
been returned, the next call should set isDone to ExprEndResult and return a
|
||||
null result. (Note it is possible to return an empty set by doing this on
|
||||
the first call.)
|
||||
|
||||
As of 7.3, the ReturnSetInfo node also contains a link to the ExprContext
|
||||
within which the function is being evaluated. This is useful for functions
|
||||
The ReturnSetInfo node also contains a link to the ExprContext within which
|
||||
the function is being evaluated. This is useful for value-per-call functions
|
||||
that need to close down internal state when they are not run to completion:
|
||||
they can register a shutdown callback function in the ExprContext.
|
||||
|
||||
Materialize mode works like this: the function creates a Tuplestore holding
|
||||
the (possibly empty) result set, and returns it. There are no multiple calls.
|
||||
The function must also return a TupleDesc that indicates the tuple structure.
|
||||
The Tuplestore and TupleDesc should be created in the context
|
||||
econtext->ecxt_per_query_memory (note this will *not* be the context the
|
||||
function is called in). The function stores pointers to the Tuplestore and
|
||||
TupleDesc into ReturnSetInfo, sets returnMode to indicate materialize mode,
|
||||
and returns null. isDone is not used and should be left at ExprSingleResult.
|
||||
|
||||
There is no support for functions accepting sets; instead, the function will
|
||||
be called multiple times, once for each element of the input set.
|
||||
|
||||
|
||||
Notes about function handlers
|
||||
-----------------------------
|
||||
|
||||
Reference in New Issue
Block a user