]> granicus.if.org Git - postgresql/blob - src/include/funcapi.h
Fix issues around the "variable" support in the lwlock infrastructure.
[postgresql] / src / include / funcapi.h
1 /*-------------------------------------------------------------------------
2  *
3  * funcapi.h
4  *        Definitions for functions which return composite type and/or sets
5  *
6  * This file must be included by all Postgres modules that either define
7  * or call FUNCAPI-callable functions or macros.
8  *
9  *
10  * Copyright (c) 2002-2015, PostgreSQL Global Development Group
11  *
12  * src/include/funcapi.h
13  *
14  *-------------------------------------------------------------------------
15  */
16 #ifndef FUNCAPI_H
17 #define FUNCAPI_H
18
19 #include "fmgr.h"
20 #include "access/tupdesc.h"
21 #include "executor/executor.h"
22 #include "executor/tuptable.h"
23
24
25 /*-------------------------------------------------------------------------
26  *      Support to ease writing Functions returning composite types
27  *-------------------------------------------------------------------------
28  *
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.
34  */
35 typedef struct AttInMetadata
36 {
37         /* full TupleDesc */
38         TupleDesc       tupdesc;
39
40         /* array of attribute type input function finfo */
41         FmgrInfo   *attinfuncs;
42
43         /* array of attribute type i/o parameter OIDs */
44         Oid                *attioparams;
45
46         /* array of attribute typmod */
47         int32      *atttypmods;
48 } AttInMetadata;
49
50 /*-------------------------------------------------------------------------
51  *              Support struct to ease writing Set Returning Functions (SRFs)
52  *-------------------------------------------------------------------------
53  *
54  * This struct holds function context for Set Returning Functions.
55  * Use fn_extra to hold a pointer to it across calls
56  */
57 typedef struct FuncCallContext
58 {
59         /*
60          * Number of times we've been called before
61          *
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.
64          */
65         uint32          call_cntr;
66
67         /*
68          * OPTIONAL maximum number of calls
69          *
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 function
72          * is done.
73          */
74         uint32          max_calls;
75
76         /*
77          * OPTIONAL pointer to result slot
78          *
79          * This is obsolete and only present for backwards compatibility, viz,
80          * user-defined SRFs that use the deprecated TupleDescGetSlot().
81          */
82         TupleTableSlot *slot;
83
84         /*
85          * OPTIONAL pointer to miscellaneous user-provided context information
86          *
87          * user_fctx is for use as a pointer to your own struct to retain
88          * arbitrary context information between calls of your function.
89          */
90         void       *user_fctx;
91
92         /*
93          * OPTIONAL pointer to struct containing attribute type input metadata
94          *
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 if
97          * you intend to use BuildTupleFromCStrings() to create the return tuple.
98          */
99         AttInMetadata *attinmeta;
100
101         /*
102          * memory context used for structures that must live for multiple calls
103          *
104          * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
105          * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
106          * context for any memory that is to be reused across multiple calls of
107          * the SRF.
108          */
109         MemoryContext multi_call_memory_ctx;
110
111         /*
112          * OPTIONAL pointer to struct containing tuple description
113          *
114          * tuple_desc is for use when returning tuples (i.e. composite data types)
115          * and is only needed if you are going to build the tuples with
116          * heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that
117          * the TupleDesc pointer stored here should usually have been run through
118          * BlessTupleDesc() first.
119          */
120         TupleDesc       tuple_desc;
121
122 } FuncCallContext;
123
124 /*----------
125  *      Support to ease writing functions returning composite types
126  *
127  * External declarations:
128  * get_call_result_type:
129  *              Given a function's call info record, determine the kind of datatype
130  *              it is supposed to return.  If resultTypeId isn't NULL, *resultTypeId
131  *              receives the actual datatype OID (this is mainly useful for scalar
132  *              result types).  If resultTupleDesc isn't NULL, *resultTupleDesc
133  *              receives a pointer to a TupleDesc when the result is of a composite
134  *              type, or NULL when it's a scalar result or the rowtype could not be
135  *              determined.  NB: the tupledesc should be copied if it is to be
136  *              accessed over a long period.
137  * get_expr_result_type:
138  *              Given an expression node, return the same info as for
139  *              get_call_result_type.  Note: the cases in which rowtypes cannot be
140  *              determined are different from the cases for get_call_result_type.
141  * get_func_result_type:
142  *              Given only a function's OID, return the same info as for
143  *              get_call_result_type.  Note: the cases in which rowtypes cannot be
144  *              determined are different from the cases for get_call_result_type.
145  *              Do *not* use this if you can use one of the others.
146  *----------
147  */
148
149 /* Type categories for get_call_result_type and siblings */
150 typedef enum TypeFuncClass
151 {
152         TYPEFUNC_SCALAR,                        /* scalar result type */
153         TYPEFUNC_COMPOSITE,                     /* determinable rowtype result */
154         TYPEFUNC_RECORD,                        /* indeterminate rowtype result */
155         TYPEFUNC_OTHER                          /* bogus type, eg pseudotype */
156 } TypeFuncClass;
157
158 extern TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,
159                                          Oid *resultTypeId,
160                                          TupleDesc *resultTupleDesc);
161 extern TypeFuncClass get_expr_result_type(Node *expr,
162                                          Oid *resultTypeId,
163                                          TupleDesc *resultTupleDesc);
164 extern TypeFuncClass get_func_result_type(Oid functionId,
165                                          Oid *resultTypeId,
166                                          TupleDesc *resultTupleDesc);
167
168 extern bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes,
169                                                          char *argmodes,
170                                                          Node *call_expr);
171
172 extern int get_func_arg_info(HeapTuple procTup,
173                                   Oid **p_argtypes, char ***p_argnames,
174                                   char **p_argmodes);
175
176 extern int get_func_input_arg_names(Datum proargnames, Datum proargmodes,
177                                                  char ***arg_names);
178
179 extern int      get_func_trftypes(HeapTuple procTup, Oid **p_trftypes);
180 extern char *get_func_result_name(Oid functionId);
181
182 extern TupleDesc build_function_result_tupdesc_d(Datum proallargtypes,
183                                                                 Datum proargmodes,
184                                                                 Datum proargnames);
185 extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple);
186
187
188 /*----------
189  *      Support to ease writing functions returning composite types
190  *
191  * External declarations:
192  * TupleDesc BlessTupleDesc(TupleDesc tupdesc) - "Bless" a completed tuple
193  *              descriptor so that it can be used to return properly labeled tuples.
194  *              You need to call this if you are going to use heap_form_tuple directly.
195  *              TupleDescGetAttInMetadata does it for you, however, so no need to call
196  *              it if you call TupleDescGetAttInMetadata.
197  * AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Build an
198  *              AttInMetadata struct based on the given TupleDesc. AttInMetadata can
199  *              be used in conjunction with C strings to produce a properly formed
200  *              tuple.
201  * HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) -
202  *              build a HeapTuple given user data in C string form. values is an array
203  *              of C strings, one for each attribute of the return tuple.
204  * Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple) - convert a
205  *              HeapTupleHeader to a Datum.
206  *
207  * Macro declarations:
208  * HeapTupleGetDatum(HeapTuple tuple) - convert a HeapTuple to a Datum.
209  *
210  * Obsolete routines and macros:
211  * TupleDesc RelationNameGetTupleDesc(const char *relname) - Use to get a
212  *              TupleDesc based on a named relation.
213  * TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to get a
214  *              TupleDesc based on a type OID.
215  * TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc) - Builds a
216  *              TupleTableSlot, which is not needed anymore.
217  * TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum
218  *              given a tuple and a slot.
219  *----------
220  */
221
222 #define HeapTupleGetDatum(tuple)                HeapTupleHeaderGetDatum((tuple)->t_data)
223 /* obsolete version of above */
224 #define TupleGetDatum(_slot, _tuple)    HeapTupleGetDatum(_tuple)
225
226 extern TupleDesc RelationNameGetTupleDesc(const char *relname);
227 extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases);
228
229 /* from execTuples.c */
230 extern TupleDesc BlessTupleDesc(TupleDesc tupdesc);
231 extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc);
232 extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values);
233 extern Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple);
234 extern TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc);
235
236
237 /*----------
238  *              Support for Set Returning Functions (SRFs)
239  *
240  * The basic API for SRFs looks something like:
241  *
242  * Datum
243  * my_Set_Returning_Function(PG_FUNCTION_ARGS)
244  * {
245  *      FuncCallContext    *funcctx;
246  *      Datum                           result;
247  *      MemoryContext           oldcontext;
248  *      <user defined declarations>
249  *
250  *      if (SRF_IS_FIRSTCALL())
251  *      {
252  *              funcctx = SRF_FIRSTCALL_INIT();
253  *              // switch context when allocating stuff to be used in later calls
254  *              oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
255  *              <user defined code>
256  *              <if returning composite>
257  *                      <build TupleDesc, and perhaps AttInMetaData>
258  *              <endif returning composite>
259  *              <user defined code>
260  *              // return to original context when allocating transient memory
261  *              MemoryContextSwitchTo(oldcontext);
262  *      }
263  *      <user defined code>
264  *      funcctx = SRF_PERCALL_SETUP();
265  *      <user defined code>
266  *
267  *      if (funcctx->call_cntr < funcctx->max_calls)
268  *      {
269  *              <user defined code>
270  *              <obtain result Datum>
271  *              SRF_RETURN_NEXT(funcctx, result);
272  *      }
273  *      else
274  *              SRF_RETURN_DONE(funcctx);
275  * }
276  *
277  *----------
278  */
279
280 /* from funcapi.c */
281 extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS);
282 extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS);
283 extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx);
284
285 #define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL)
286
287 #define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo)
288
289 #define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo)
290
291 #define SRF_RETURN_NEXT(_funcctx, _result) \
292         do { \
293                 ReturnSetInfo      *rsi; \
294                 (_funcctx)->call_cntr++; \
295                 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
296                 rsi->isDone = ExprMultipleResult; \
297                 PG_RETURN_DATUM(_result); \
298         } while (0)
299
300 #define SRF_RETURN_NEXT_NULL(_funcctx) \
301         do { \
302                 ReturnSetInfo      *rsi; \
303                 (_funcctx)->call_cntr++; \
304                 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
305                 rsi->isDone = ExprMultipleResult; \
306                 PG_RETURN_NULL(); \
307         } while (0)
308
309 #define  SRF_RETURN_DONE(_funcctx) \
310         do { \
311                 ReturnSetInfo      *rsi; \
312                 end_MultiFuncCall(fcinfo, _funcctx); \
313                 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
314                 rsi->isDone = ExprEndResult; \
315                 PG_RETURN_NULL(); \
316         } while (0)
317
318 #endif   /* FUNCAPI_H */