"executor/executor.h" /* for GetAttributeByName() */
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(c_overpaid);
Datum
c_overpaid(PG_FUNCTION_ARGS)
{
HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
int32 limit = PG_GETARG_INT32(1);
bool isnull;
Datum salary;
salary = GetAttributeByName(t, "salary", &isnull);
if (isnull)
PG_RETURN_BOOL(false);
/* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */
PG_RETURN_BOOL(DatumGetInt32(salary) > limit);
}
]]>
</programlisting>
</para>
<para>
<function>GetAttributeByName</function> is the
<productname>PostgreSQL</productname> system function that
returns attributes out of the specified row. It has
three arguments: the argument of type <type>HeapTupleHeader</type> passed
into
the function, the name of the desired attribute, and a
return parameter that tells whether the attribute
is null. <function>GetAttributeByName</function> returns a <type>Datum</type>
value that you can convert to the proper data type by using the
appropriate <function>DatumGet<replaceable>XXX</replaceable>()</function>
function. Note that the return value is meaningless if the null flag is
set; always check the null flag before trying to do anything with the
result.
</para>
<para>
There is also <function>GetAttributeByNum</function>, which selects
the target attribute by column number instead of name.
</para>
<para>
The following command declares the function
<function>c_overpaid</function> in SQL:
<programlisting>
CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean
AS '<replaceable>DIRECTORY</replaceable>/funcs', 'c_overpaid'
LANGUAGE C STRICT;
</programlisting>
Notice we have used <literal>STRICT</literal> so that we did not have to
check whether the input arguments were NULL.
</para>
</sect2>
<sect2 id="xfunc-c-returning-rows">
<title>Returning Rows (Composite Types)</title>
<para>
To return a row or composite-type value from a C-language
function, you can use a special API that provides macros and
functions to hide most of the complexity of building composite
data types. To use this API, the source file must include:
<programlisting>
#include "funcapi.h"
</programlisting>
</para>
<para>
There are two ways you can build a composite data value (henceforth
a <quote>tuple</quote>): you can build it from an array of Datum values,
or from an array of C strings that can be passed to the input
conversion functions of the tuple's column data types. In either
case, you first need to obtain or construct a <structname>TupleDesc</structname>
descriptor for the tuple structure. When working with Datums, you
pass the <structname>TupleDesc</structname> to <function>BlessTupleDesc</function>,
and then call <function>heap_form_tuple</function> for each row. When working
with C strings, you pass the <structname>TupleDesc</structname> to
<function>TupleDescGetAttInMetadata</function>, and then call
<function>BuildTupleFromCStrings</function> for each row. In the case of a
function returning a set of tuples, the setup steps can all be done
once during the first call of the function.
</para>
<para>
Several helper functions are available for setting up the needed
<structname>TupleDesc</structname>. The recommended way to do this in most
functions returning composite values is to call:
<programlisting>
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,
Oid *resultTypeId,
TupleDesc *resultTupleDesc)
</programlisting>
passing the same <literal>fcinfo</literal> struct passed to the calling function
itself. (This of course requires that you use the version-1
calling conventions.) <varname>resultTypeId</varname>