| The PostgreSQL 9.0 Reference Manual - Volume 2 - Programming Guide
by The PostgreSQL Global Development Group Paperback (6"x9"), 478 pages ISBN 9781906966065 RRP £14.95 ($19.95) Sales of this book support the PostgreSQL project! Get a printed copy>>> |
5.9.9 Returning Rows (Composite Types)
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:
#include "funcapi.h"
There are two ways you can build a composite data value (henceforth
a “tuple”): 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 TupleDesc
descriptor for the tuple structure. When working with Datums, you
pass the TupleDesc to BlessTupleDesc,
and then call heap_form_tuple for each row. When working
with C strings, you pass the TupleDesc to
TupleDescGetAttInMetadata, and then call
BuildTupleFromCStrings 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.
Several helper functions are available for setting up the needed
TupleDesc. The recommended way to do this in most
functions returning composite values is to call:
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,
Oid *resultTypeId,
TupleDesc *resultTupleDesc)
passing the same fcinfo struct passed to the calling function
itself. (This of course requires that you use the version-1
calling conventions.) resultTypeId can be specified
as NULL or as the address of a local variable to receive the
function's result type OID. resultTupleDesc should be the
address of a local TupleDesc variable. Check that the
result is TYPEFUNC_COMPOSITE; if so,
resultTupleDesc has been filled with the needed
TupleDesc. (If it is not, you can report an error along
the lines of “function returning record called in context that
cannot accept type record”.)
Tip:
get_call_result_typecan resolve the actual type of a polymorphic function result; so it is useful in functions that return scalar polymorphic results, not only functions that return composites. TheresultTypeIdoutput is primarily useful for functions returning polymorphic scalars.
Note:
get_call_result_typehas a siblingget_expr_result_type, which can be used to resolve the expected output type for a function call represented by an expression tree. This can be used when trying to determine the result type from outside the function itself. There is alsoget_func_result_type, which can be used when only the function's OID is available. However these functions are not able to deal with functions declared to returnrecord, andget_func_result_typecannot resolve polymorphic types, so you should preferentially useget_call_result_type.
Older, now-deprecated functions for obtaining
TupleDescs are:
TupleDesc RelationNameGetTupleDesc(const char *relname)
to get a TupleDesc for the row type of a named relation,
and:
TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)
to get a TupleDesc based on a type OID. This can
be used to get a TupleDesc for a base or
composite type. It will not work for a function that returns
record, however, and it cannot resolve polymorphic
types.
Once you have a TupleDesc, call:
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
if you plan to work with Datums, or:
AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc)
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
FuncCallContext structure--use the
tuple_desc or attinmeta field
respectively.
When working with Datums, use:
HeapTuple heap_form_tuple(TupleDesc tupdesc, Datum *values, bool *isnull)
to build a HeapTuple given user data in Datum form.
When working with C strings, use:
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
to build a HeapTuple given user data
in C string form. values 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 values array
should be set to NULL. This function will need to
be called again for each row you return.
Once you have built a tuple to return from your function, it
must be converted into a Datum. Use:
HeapTupleGetDatum(HeapTuple tuple)
to convert a HeapTuple into a valid Datum. This
Datum 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.
An example appears in the next section.
| ISBN 9781906966065 | The PostgreSQL 9.0 Reference Manual - Volume 2 - Programming Guide | See the print edition |