Home Explore Blog CI



postgresql

40th chunk of `doc/src/sgml/xfunc.sgml`
5211cee7d382d700ab886884e0f9f396a2ae5d240c3b63570000000100000fa0
 time) and it returns one new row on each call, until
     it has no more rows to return and signals that by returning NULL.
     The set-returning function (<acronym>SRF</acronym>) must therefore
     save enough state across calls to remember what it was doing and
     return the correct next item on each call.
     In the other method, called <firstterm>Materialize</firstterm> mode,
     an SRF fills and returns a tuplestore object containing its
     entire result; then only one call occurs for the whole result, and
     no inter-call state is needed.
    </para>

    <para>
     When using ValuePerCall mode, it is important to remember that the
     query is not guaranteed to be run to completion; that is, due to
     options such as <literal>LIMIT</literal>, the executor might stop
     making calls to the set-returning function before all rows have been
     fetched.  This means it is not safe to perform cleanup activities in
     the last call, because that might not ever happen.  It's recommended
     to use Materialize mode for functions that need access to external
     resources, such as file descriptors.
    </para>

    <para>
     The remainder of this section documents a set of helper macros that
     are commonly used (though not required to be used) for SRFs using
     ValuePerCall mode.  Additional details about Materialize mode can be
     found in <filename>src/backend/utils/fmgr/README</filename>.  Also,
     the <filename>contrib</filename> modules in
     the <productname>PostgreSQL</productname> source distribution contain
     many examples of SRFs using both ValuePerCall and Materialize mode.
    </para>

    <para>
     To use the ValuePerCall support macros described here,
     include <filename>funcapi.h</filename>.  These macros work with a
     structure <structname>FuncCallContext</structname> that contains the
     state that needs to be saved across calls.  Within the calling
     SRF, <literal>fcinfo-&gt;flinfo-&gt;fn_extra</literal> is used to
     hold a pointer to <structname>FuncCallContext</structname> across
     calls.  The macros automatically fill that field on first use,
     and expect to find the same pointer there on subsequent uses.
<programlisting>
typedef struct FuncCallContext
{
    /*
     * Number of times we've been called before
     *
     * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and
     * incremented for you every time SRF_RETURN_NEXT() is called.
     */
    uint64 call_cntr;

    /*
     * OPTIONAL maximum number of calls
     *
     * max_calls is here for convenience only and setting it is optional.
     * If not set, you must provide alternative means to know when the
     * function is done.
     */
    uint64 max_calls;

    /*
     * OPTIONAL pointer to miscellaneous user-provided context information
     *
     * user_fctx is for use as a pointer to your own data to retain
     * arbitrary context information between calls of your function.
     */
    void *user_fctx;

    /*
     * OPTIONAL pointer to struct containing attribute type input metadata
     *
     * attinmeta is for use when returning tuples (i.e., composite data types)
     * and is not used when returning base data types. It is only needed
     * if you intend to use BuildTupleFromCStrings() to create the return
     * tuple.
     */
    AttInMetadata *attinmeta;

    /*
     * memory context used for structures that must live for multiple calls
     *
     * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
     * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
     * context for any memory that is to be reused across multiple calls
     * of the SRF.
     */
    MemoryContext multi_call_memory_ctx;

    /*
     * OPTIONAL pointer to struct containing tuple description
     *
     * tuple_desc is for use when returning tuples (i.e., composite data types)
     * and is only needed if you are going to build the tuples with
     *

Title: ValuePerCall vs Materialize Modes and the FuncCallContext Structure
Summary
This section elaborates on the ValuePerCall and Materialize modes for C-language set-returning functions (SRFs) in PostgreSQL. It highlights the importance of avoiding cleanup activities in the last call of ValuePerCall mode due to potential query interruptions and suggests using Materialize mode for functions needing external resource access. It introduces helper macros for ValuePerCall mode, which rely on the `FuncCallContext` structure to maintain state across calls. The `FuncCallContext` structure, defined in `funcapi.h`, contains fields such as `call_cntr`, `max_calls`, `user_fctx`, `attinmeta`, `multi_call_memory_ctx`, and `tuple_desc` for managing call counts, user-defined context, attribute metadata, memory context, and tuple descriptions, respectively.