</programlisting>
to get a <structname>TupleDesc</structname> for the row type of a named relation,
and:
<programlisting>
TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)
</programlisting>
to get a <structname>TupleDesc</structname> based on a type OID. This can
be used to get a <structname>TupleDesc</structname> for a base or
composite type. It will not work for a function that returns
<structname>record</structname>, however, and it cannot resolve polymorphic
types.
</para>
<para>
Once you have a <structname>TupleDesc</structname>, call:
<programlisting>
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
</programlisting>
if you plan to work with Datums, or:
<programlisting>
AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc)
</programlisting>
if you plan to work with C strings. If you are writing a function
returning set, you can save the results of these functions in the
<structname>FuncCallContext</structname> structure — use the
<structfield>tuple_desc</structfield> or <structfield>attinmeta</structfield> field
respectively.
</para>
<para>
When working with Datums, use:
<programlisting>
HeapTuple heap_form_tuple(TupleDesc tupdesc, Datum *values, bool *isnull)
</programlisting>
to build a <structname>HeapTuple</structname> given user data in Datum form.
</para>
<para>
When working with C strings, use:
<programlisting>
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
</programlisting>
to build a <structname>HeapTuple</structname> given user data
in C string form. <parameter>values</parameter> is an array of C strings,
one for each attribute of the return row. Each C string should be in
the form expected by the input function of the attribute data
type. In order to return a null value for one of the attributes,
the corresponding pointer in the <parameter>values</parameter> array
should be set to <symbol>NULL</symbol>. This function will need to
be called again for each row you return.
</para>
<para>
Once you have built a tuple to return from your function, it
must be converted into a <type>Datum</type>. Use:
<programlisting>
HeapTupleGetDatum(HeapTuple tuple)
</programlisting>
to convert a <structname>HeapTuple</structname> into a valid Datum. This
<type>Datum</type> can be returned directly if you intend to return
just a single row, or it can be used as the current return value
in a set-returning function.
</para>
<para>
An example appears in the next section.
</para>
</sect2>
<sect2 id="xfunc-c-return-set">
<title>Returning Sets</title>
<para>
C-language functions have two options for returning sets (multiple
rows). In one method, called <firstterm>ValuePerCall</firstterm>
mode, a set-returning function is called repeatedly (passing the same
arguments each 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.