Database Reference
In-Depth Information
In the preceding example,
GetAttributeByName(th, "b", &bisnull)
returns
a Datum, and it can return something even when the field in the tuple is
NULL
,
so always check for null-ness first. Also, the returned Datum itself cannot be used
for much unless we convert it to some real type, as done in the next step using
DatumGetInt32()
, which simply converts the vague
Datum
to a real
int32
value,
basically doing a cast form a memory location of an undefined type to
int32
.
The definition of
Datum
in
postgresql.h
is
typedef Datum *DatumPtr;
that is
anything pointed to by a
DatumPtr
. Even though
DatumPtr
is defined as
typedef
uintptr_t Datum;
it may be easier to think of it as a (slightly restricted)
void *
.
Once more, any real substance is added to a
Datum
by converting it to a real type.
You can also go the other way, turning almost anything into a
Datum
as seen at the
end of the function:
HeapTupleGetDatum( rettuple )
Again, for anything else in PostgreSQL to make use of such
Datum
, the type inform-
ation must be available somewhere else, in our case the return type definitions of the
function.
Returning a set of records
Next, we modify our function to not just return a single record of re-ordered fields
from argument record, but to return all possible orderings. We still add one extra field
'x'
as an example of how you can use the values you extracted from the argument.
For set-returning functions, PostgreSQL has a special calling mechanism, where
PostgreSQL's executor machinery will keep calling the function over and over again
until it reports back that it does not have any more values to return. This return-
and-continue behavior is very similar to how the
yield
keyword works in Python or
JavaScript. All calls to the set returning function get an argument, a persistent struc-
ture maintained outside the function and made available to the function via macros:
SRF_FIRSTCALL_INIT()
for the first call and
SRF_PERCALL_SETUP()
for subse-
quent calls.