1
/*-------------------------------------------------------------------------
4
* Definitions for functions which return composite type and/or sets
6
* This file must be included by all Postgres modules that either define
7
* or call FUNCAPI-callable functions or macros.
10
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
12
* $PostgreSQL: pgsql/src/include/funcapi.h,v 1.15 2005-01-01 05:43:08 momjian Exp $
14
*-------------------------------------------------------------------------
20
#include "access/tupdesc.h"
21
#include "executor/executor.h"
22
#include "executor/tuptable.h"
25
/*-------------------------------------------------------------------------
26
* Support to ease writing Functions returning composite types
27
*-------------------------------------------------------------------------
29
* This struct holds arrays of individual attribute information
30
* needed to create a tuple from raw C strings. It also requires
31
* a copy of the TupleDesc. The information carried here
32
* is derived from the TupleDesc, but it is stored here to
33
* avoid redundant cpu cycles on each call to an SRF.
35
typedef struct AttInMetadata
40
/* array of attribute type input function finfo */
43
/* array of attribute type i/o parameter OIDs */
46
/* array of attribute typmod */
50
/*-------------------------------------------------------------------------
51
* Support struct to ease writing Set Returning Functions (SRFs)
52
*-------------------------------------------------------------------------
54
* This struct holds function context for Set Returning Functions.
55
* Use fn_extra to hold a pointer to it across calls
57
typedef struct FuncCallContext
60
* Number of times we've been called before
62
* call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and
63
* incremented for you every time SRF_RETURN_NEXT() is called.
68
* OPTIONAL maximum number of calls
70
* max_calls is here for convenience only and setting it is optional. If
71
* not set, you must provide alternative means to know when the
77
* OPTIONAL pointer to result slot
79
* This is obsolete and only present for backwards compatibility, viz,
80
* user-defined SRFs that use the deprecated TupleDescGetSlot().
85
* OPTIONAL pointer to miscellaneous user-provided context information
87
* user_fctx is for use as a pointer to your own struct to retain
88
* arbitrary context information between calls of your function.
93
* OPTIONAL pointer to struct containing attribute type input metadata
95
* attinmeta is for use when returning tuples (i.e. composite data types)
96
* and is not used when returning base data types. It is only needed
97
* if you intend to use BuildTupleFromCStrings() to create the return
100
AttInMetadata *attinmeta;
103
* memory context used for structures that must live for multiple
106
* multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
107
* by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
108
* context for any memory that is to be reused across multiple calls
111
MemoryContext multi_call_memory_ctx;
114
* OPTIONAL pointer to struct containing tuple description
116
* tuple_desc is for use when returning tuples (i.e. composite data
117
* types) and is only needed if you are going to build the tuples with
118
* heap_formtuple() rather than with BuildTupleFromCStrings(). Note
119
* that the TupleDesc pointer stored here should usually have been run
120
* through BlessTupleDesc() first.
122
TupleDesc tuple_desc;
127
* Support to ease writing Functions returning composite types
129
* External declarations:
130
* TupleDesc RelationNameGetTupleDesc(const char *relname) - Use to get a
131
* TupleDesc based on a specified relation.
132
* TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to get a
133
* TupleDesc based on a type OID. This can be used to get
134
* a TupleDesc for a base (scalar) or composite (relation) type.
135
* TupleDesc BlessTupleDesc(TupleDesc tupdesc) - "Bless" a completed tuple
136
* descriptor so that it can be used to return properly labeled tuples.
137
* You need to call this if you are going to use heap_formtuple directly.
138
* TupleDescGetAttInMetadata does it for you, however, so no need to call
139
* it if you call TupleDescGetAttInMetadata.
140
* AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Build an
141
* AttInMetadata struct based on the given TupleDesc. AttInMetadata can
142
* be used in conjunction with C strings to produce a properly formed
144
* HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) -
145
* build a HeapTuple given user data in C string form. values is an array
146
* of C strings, one for each attribute of the return tuple.
148
* Macro declarations:
149
* HeapTupleGetDatum(HeapTuple tuple) - convert a HeapTuple to a Datum.
151
* Obsolete routines and macros:
152
* TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc) - Builds a
153
* TupleTableSlot, which is not needed anymore.
154
* TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum
155
* given a tuple and a slot.
159
#define HeapTupleGetDatum(_tuple) PointerGetDatum((_tuple)->t_data)
160
/* obsolete version of above */
161
#define TupleGetDatum(_slot, _tuple) PointerGetDatum((_tuple)->t_data)
164
extern TupleDesc RelationNameGetTupleDesc(const char *relname);
165
extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases);
167
/* from execTuples.c */
168
extern TupleDesc BlessTupleDesc(TupleDesc tupdesc);
169
extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc);
170
extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values);
171
extern TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc);
175
* Support for Set Returning Functions (SRFs)
177
* The basic API for SRFs looks something like:
180
* my_Set_Returning_Function(PG_FUNCTION_ARGS)
182
* FuncCallContext *funcctx;
184
* MemoryContext oldcontext;
185
* <user defined declarations>
187
* if (SRF_IS_FIRSTCALL())
189
* funcctx = SRF_FIRSTCALL_INIT();
190
* // switch context when allocating stuff to be used in later calls
191
* oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
192
* <user defined code>
193
* <if returning composite>
194
* <build TupleDesc, and perhaps AttInMetaData>
195
* <endif returning composite>
196
* <user defined code>
197
* // return to original context when allocating transient memory
198
* MemoryContextSwitchTo(oldcontext);
200
* <user defined code>
201
* funcctx = SRF_PERCALL_SETUP();
202
* <user defined code>
204
* if (funcctx->call_cntr < funcctx->max_calls)
206
* <user defined code>
207
* <obtain result Datum>
208
* SRF_RETURN_NEXT(funcctx, result);
211
* SRF_RETURN_DONE(funcctx);
218
extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS);
219
extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS);
220
extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx);
222
#define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL)
224
#define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo)
226
#define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo)
228
#define SRF_RETURN_NEXT(_funcctx, _result) \
230
ReturnSetInfo *rsi; \
231
(_funcctx)->call_cntr++; \
232
rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
233
rsi->isDone = ExprMultipleResult; \
234
PG_RETURN_DATUM(_result); \
237
#define SRF_RETURN_DONE(_funcctx) \
239
ReturnSetInfo *rsi; \
240
end_MultiFuncCall(fcinfo, _funcctx); \
241
rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
242
rsi->isDone = ExprEndResult; \
246
#endif /* FUNCAPI_H */