Home Explore Blog CI



postgresql

44th chunk of `doc/src/sgml/xfunc.sgml`
0a67f3cc41e93c5ccd583d7571e7c3e5063b6e94944348030000000100000fa0
 '<replaceable>filename</replaceable>', 'retcomposite'
    LANGUAGE C IMMUTABLE STRICT;
</programlisting>
     A different way is to use OUT parameters:
<programlisting>
CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,
    OUT f1 integer, OUT f2 integer, OUT f3 integer)
    RETURNS SETOF record
    AS '<replaceable>filename</replaceable>', 'retcomposite'
    LANGUAGE C IMMUTABLE STRICT;
</programlisting>
     Notice that in this method the output type of the function is formally
     an anonymous <structname>record</structname> type.
    </para>
   </sect2>

   <sect2 id="xfunc-c-polymorphic">
    <title>Polymorphic Arguments and Return Types</title>

    <para>
     C-language functions can be declared to accept and
     return the polymorphic types described in <xref
     linkend="extend-types-polymorphic"/>.
     When a function's arguments or return types
     are defined as polymorphic types, the function author cannot know
     in advance what data type it will be called with, or
     need to return. There are two routines provided in <filename>fmgr.h</filename>
     to allow a version-1 C function to discover the actual data types
     of its arguments and the type it is expected to return. The routines are
     called <literal>get_fn_expr_rettype(FmgrInfo *flinfo)</literal> and
     <literal>get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)</literal>.
     They return the result or argument type OID, or <symbol>InvalidOid</symbol> if the
     information is not available.
     The structure <literal>flinfo</literal> is normally accessed as
     <literal>fcinfo-&gt;flinfo</literal>. The parameter <literal>argnum</literal>
     is zero based.  <function>get_call_result_type</function> can also be used
     as an alternative to <function>get_fn_expr_rettype</function>.
     There is also <function>get_fn_expr_variadic</function>, which can be used to
     find out whether variadic arguments have been merged into an array.
     This is primarily useful for <literal>VARIADIC "any"</literal> functions,
     since such merging will always have occurred for variadic functions
     taking ordinary array types.
    </para>

    <para>
     For example, suppose we want to write a function to accept a single
     element of any type, and return a one-dimensional array of that type:

<programlisting>
PG_FUNCTION_INFO_V1(make_array);
Datum
make_array(PG_FUNCTION_ARGS)
{
    ArrayType  *result;
    Oid         element_type = get_fn_expr_argtype(fcinfo-&gt;flinfo, 0);
    Datum       element;
    bool        isnull;
    int16       typlen;
    bool        typbyval;
    char        typalign;
    int         ndims;
    int         dims[MAXDIM];
    int         lbs[MAXDIM];

    if (!OidIsValid(element_type))
        elog(ERROR, "could not determine data type of input");

    /* get the provided element, being careful in case it's NULL */
    isnull = PG_ARGISNULL(0);
    if (isnull)
        element = (Datum) 0;
    else
        element = PG_GETARG_DATUM(0);

    /* we have one dimension */
    ndims = 1;
    /* and one element */
    dims[0] = 1;
    /* and lower bound is 1 */
    lbs[0] = 1;

    /* get required info about the element type */
    get_typlenbyvalalign(element_type, &amp;typlen, &amp;typbyval, &amp;typalign);

    /* now build the array */
    result = construct_md_array(&amp;element, &amp;isnull, ndims, dims, lbs,
                                element_type, typlen, typbyval, typalign);

    PG_RETURN_ARRAYTYPE_P(result);
}
</programlisting>
    </para>

    <para>
     The following command declares the function
     <function>make_array</function> in SQL:

<programlisting>
CREATE FUNCTION make_array(anyelement) RETURNS anyarray
    AS '<replaceable>DIRECTORY</replaceable>/funcs', 'make_array'
    LANGUAGE C IMMUTABLE;
</programlisting>
    </para>

    <para>
     There is a variant of polymorphism that is only available to C-language
     functions: they can be declared to take parameters of type
    

Title: Polymorphic Arguments and Return Types in C Functions
Summary
C-language functions can use polymorphic types for arguments and return values. The fmgr.h header provides functions like get_fn_expr_rettype and get_fn_expr_argtype to determine the actual data types during runtime. These functions return the OID of the type or InvalidOid if the information is unavailable. Additionally, get_fn_expr_variadic checks if variadic arguments have been merged into an array. The example shows how to create a function that accepts an element of any type and returns a one-dimensional array of that type, using functions like construct_md_array. Finally, it gives an SQL command to declare the example function in SQL.